paperclipai/paperclip · warning
[plugin-kubernetes] egressMode=standard cannot enforce FQDN-
Error message
[plugin-kubernetes] egressMode=standard cannot enforce FQDN-based egress rules. The following FQDNs are reachable only via operator-supplied egressAllowCidrs: ${totalFqdnsForWarn.join(", ")}. Switch egressMode to "cilium" for exact FQDN allow-listing. What it means
Variant of the standard-mode egress warning: FQDN allow-lists are configured AND operator-supplied egressAllowCidrs exist. The FQDNs are reachable only through those CIDRs — standard NetworkPolicy cannot bind rules to hostnames. If a target service's IPs rotate (CDNs, provider endpoints), egress breaks silently because the CIDR list no longer matches.
Source
Thrown at packages/plugins/sandbox-providers/kubernetes/src/plugin.ts:323
// The adapter for THIS run is the agent's adapter (params.adapterType) when
// supplied, so one environment can serve mixed harnesses; otherwise fall back
// to the environment's configured default adapter. getAdapterDefaults validates
// it is a registered adapter (throws otherwise), so a curated-out adapter fails
// the lease as before.
const effectiveAdapterType = resolveRunAdapterType(params.adapterType, config.adapterType);
// Emit a runtime warning if FQDNs are configured but egressMode=standard
// cannot enforce them. Mirrors the validateConfig warning so operators see
// it in paperclip-server logs even if they missed the validation step.
const adapterDefaultsForWarn = getAdapterDefaults(effectiveAdapterType, config.adapters);
const totalFqdnsForWarn = [...adapterDefaultsForWarn.allowFqdns, ...config.egressAllowFqdns];
if (config.egressMode === "standard" && totalFqdnsForWarn.length > 0) {
if (config.egressAllowCidrs.length === 0) {
console.warn(
`[plugin-kubernetes] egressMode=standard cannot enforce FQDN-based egress rules; falling back to public-IPv4 (TCP 80/443) with private/link-local ranges excluded so the configured FQDNs (${totalFqdnsForWarn.join(", ")}) remain reachable. Switch egressMode to "cilium" for exact FQDN allow-listing.`,
);
} else {
console.warn(
`[plugin-kubernetes] egressMode=standard cannot enforce FQDN-based egress rules. The following FQDNs are reachable only via operator-supplied egressAllowCidrs: ${totalFqdnsForWarn.join(", ")}. Switch egressMode to "cilium" for exact FQDN allow-listing.`,
);
}
}
const kc = createKubeConfig({
inCluster: config.inCluster,
kubeconfig: config.kubeconfig,
});
const clients = makeKubeClients(kc);
// Ensure the tenant namespace and all its RBAC / network policy resources
// exist before we try to create the Job.
const adapterDefaults = getAdapterDefaults(effectiveAdapterType, config.adapters);
await ensureTenant(clients, {
namespace,
companyId: params.companyId,View on GitHub (pinned to 120ae5428f)
Solutions
- Prefer egressMode "cilium" for hostname-exact enforcement.
- If staying on standard, automate refreshing egressAllowCidrs from the FQDNs' current DNS resolution on a schedule.
- Widen CIDRs to the provider's officially published IP ranges instead of point-in-time resolutions.
- Remove FQDNs that are no longer needed to shrink the drift surface.
Example fix
// before
{
"egressMode": "standard",
"egressAllowFqdns": ["api.anthropic.com"],
"egressAllowCidrs": ["160.79.104.0/23"]
}
// after
{
"egressMode": "cilium",
"egressAllowFqdns": ["api.anthropic.com"]
} Defensive patterns
Strategy: validation
Validate before calling
// Keep CIDRs honest: verify each FQDN still resolves into the allow-list.
import dns from 'node:dns/promises';
import ip from 'ip6addr';
async function fqdnsCoveredByCidrs(fqdns: string[], cidrs: string[]): Promise<string[]> {
const uncovered: string[] = [];
for (const fqdn of fqdns) {
const addrs = await dns.resolve4(fqdn).catch(() => [] as string[]);
const covered = addrs.some((a) => cidrs.some((c) => ip.parse(c).contains(a)));
if (!covered) uncovered.push(fqdn);
}
return uncovered;
} Prevention
- Prefer egressMode=cilium whenever the target uses CDNs or rotating IPs.
- If pinned to CIDRs, automate DNS-to-CIDR refresh on a schedule shorter than the provider's rotation period.
- Alert when a scheduled fqdnsCoveredByCidrs check returns non-empty.
- Prefer providers' published IP ranges over point-in-time DNS answers.
When it happens
Trigger: egressMode === 'standard', non-empty FQDN set, and non-empty egressAllowCidrs — the plugin emits this warn at lease creation to flag that FDN enforcement is indirect via the operator's CIDR list.
Common situations: Pinning a provider's API IPs in CIDRs; CDN IP rotation making the allow-list stale; providers publishing changing ranges; operators copying yesterday's DNS answers into config.
Related errors
- [plugin-kubernetes] egressMode=standard cannot enforce FQDN-
- ${label} had drifted migration history; repaired migration j
AI-assisted analysis of paperclipai/paperclip@120ae5428f (2026-08-18).
Data as JSON: /api/errors/8ff8b4ddbf5e5f24.
Report an issue: GitHub.