Skip to content

Explain delivery_ips_not_public when a VPN/gateway hides the caller - #6

Merged
njb90 merged 1 commit into
mainfrom
vpn-error-guidance
Aug 5, 2026
Merged

Explain delivery_ips_not_public when a VPN/gateway hides the caller#6
njb90 merged 1 commit into
mainfrom
vpn-error-guidance

Conversation

@njb90

@njb90 njb90 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

Behind a corporate VPN or secure gateway (e.g. Cloudflare WARP), the provisioning API can see the request arriving from a private address. The requester's address is always folded into the delivery allow-list, so provisioning fails with delivery_ips_not_public — no flag avoids it, and the bare 400 gives the user (or an AI agent driving the CLI) nothing to act on.

This adds guidance when that error's rejected private address was server-derived rather than user-supplied:

  • Human mode: dim stderr text after the error line, matching the existing rate-limit/registration-disabled hint pattern.
  • --json: additive hint field inside the existing error envelope (non-breaking).
  • Wording is deliberate for AI agents: names the routing cause, states explicitly it is not a security block, and instructs agents to report to the user and never change network/VPN settings themselves.
  • Suppressed when the hint would be wrong or redundant: the user passed the rejected IP via --ip (compared with IPv6 normalization, not string equality), every rejected address is public, or the message has no parseable IP while --ip values were given.
  • README gains a troubleshooting bullet for the same situation.

Lives in ip-check.ts alongside the existing delivery-IP/VPN logic and reuses its isPublicIp; not added to the public library surface.

Test plan

  • 7 unit tests: derived-private hint content, user-supplied suppression, IPv6 normalized comparison, multi-IP messages, all-public suppression, unparseable-message attribution, prose false-positives (times/hex)
  • 2 integration tests spawning the real CLI against a stub API: hint present in --json error envelope; human mode emits guidance on stderr
  • Full suite 63/63

🤖 Generated with Claude Code

The server folds the requester's address into the delivery allow-list,
so behind a corporate VPN or secure gateway the API sees a private
address and refuses — no flag avoids it, and the bare 400 reads like a
fault. Emit guidance (stderr, plus a hint field in the --json error
envelope) that names the routing cause, states it is not a security
block, and tells AI agents to defer to the user rather than touch
network settings. Suppressed when the user passed the rejected IP
themselves or the rejected addresses are public.
@njb90
njb90 merged commit c160814 into main Aug 5, 2026
4 checks passed
@njb90 njb90 mentioned this pull request Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant