Skip to content

Cloudflare Workers: document loader rejects public CNAME-backed hosts as private addresses #956

Description

@SJang1

Summary

Fedify's document loader rejects valid public ActivityPub URLs hosted on CNAME-backed custom domains when running on Cloudflare Workers with nodejs_compat.

For example, this public ActivityPub Article cannot be loaded:

https://writings.hongminhee.org/ap/articles/2026/07/fedified-blog

Fedify throws:

UrlError: Invalid or private address: hongminhee-writings.netlify.app.

writings.hongminhee.org is a public hostname whose DNS record points to hongminhee-writings.netlify.app through a CNAME.

Minimal reproduction

import { getDocumentLoader } from "@fedify/vocab-runtime";

const loader = getDocumentLoader();

await loader(
  "https://writings.hongminhee.org/ap/articles/2026/07/fedified-blog",
);

Equivalent Wrangler configuration:

{
  "compatibility_date": "2026-06-16",
  "compatibility_flags": ["nodejs_compat"]
}

Actual behavior

The call fails before the document is fetched:

UrlError: Invalid or private address: hongminhee-writings.netlify.app.

Runtime scope and likely root cause

Fedify's validatePublicUrl() calls:

addresses = await lookup(hostname, { all: true });

and then assumes that every LookupAddress.address is an IPv4 or IPv6 literal:

https://github.com/fedify-dev/fedify/blob/main/packages/vocab-runtime/src/url.ts

Under Cloudflare Workers' node:dns compatibility implementation, the lookup can return the CNAME target hostname—hongminhee-writings.netlify.app.—in the address field instead of a final IP address.

That hostname is passed to validatePublicIpAddress(), which rejects it because it is neither an IPv4 nor an IPv6 literal.

The same lookup under regular Node.js resolves to final IP addresses and does not exhibit this behavior.

Expected behavior

Fedify should successfully load the public ActivityPub document after securely resolving the CNAME target to its final A/AAAA records.

All resolved addresses should still be checked against Fedify's private and reserved address restrictions.

AI disclosure

This issue draft was created using codex:5.6-sol and fixed by @SJang1

Activity

  1. added theissue type on Jul 19, 2026
  2. dahlia commented on Jul 19, 2026

    @dahlia
    Member

    Could you work on branch 2.0-maintenance instead of main?

  3. linked a pull request that will close this issueHandle non-IP DNS lookup results #957on Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Fields

Priority

None yet

Effort

None yet

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions