https://github.com/bitcoin/bitcoin/blob/d72758c3f6c34cd835f5de3efc230964f3b1ea56/src/torcontrol.cpp#L539

If a user is running Tor proxy outside localhost (perhaps on other host inside LAN or in containerised environment) , the automatic creation of onion services ends up creating an onion service listening to hardcored 127.0.0.1 address on the Tor proxy's host instead of the private address of the bitcoind – effectively running an empty onion service listening the Tor proxy's localhost.
if (!(flags & BF_EXPLICIT) && !IsReachable(addr))
        return false;
    bilingual_str strError;
    if (!BindListenPort(addr, strError, permissions)) {
        if ((flags & BF_REPORT_ERROR) && clientInterface) {
            clientInterface->ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR);
        }
        return false;
    }
    return true;
}
bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<NetWhitebindPermissions>& whiteBinds)
{
    bool fBound = false;
    for (const auto& addrBind : binds) {
        fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR), NetPermissionFlags::PF_NONE);
    }
    for (const auto& addrBind : whiteBinds) {
        fBound |= Bind(addrBind.m_service, (BF_EXPLICIT | BF_REPORT_ERROR), addrBind.m_flags);
    }
    if (binds.empty() && whiteBinds.empty()) {
        struct in_addr inaddr_any;
        inaddr_any.s_addr = INADDR_ANY;
        struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
        fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE, NetPermissionFlags::PF_NONE);
        fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE, NetPermissionFlags::PF_NONE);
    }
    return fBound;
}
bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)