aaif-goose/goose · error · anyhow::Error
invalid --allowed-origin value `{origin}`: {error}
Error message
invalid --allowed-origin value `{origin}`: {error} What it means
anyhow error from 'goose serve' origin validation (crates/goose-cli/src/cli.rs). After the wildcard/empty check, each --allowed-origin value is parsed with HeaderValue::from_str; values containing characters illegal in an HTTP header (spaces, control bytes, non-ASCII such as a URL with a path or unicode, or trailing newline/space that survived trimming of ends) produce this wrapping error with the underlying http crate message.
Source
Thrown at crates/goose-cli/src/cli.rs:1469
if !require_token && !dangerously_unauthenticated {
anyhow::bail!(
"{GOOSE_SERVER_SECRET_KEY_ENV} must be set to start `goose serve`; pass --dangerously-unauthenticated to run without ACP authentication"
);
}
if dangerously_unauthenticated && !require_token {
warn!(
"{GOOSE_SERVER_SECRET_KEY_ENV} is not set and --dangerously-unauthenticated was passed; the ACP endpoint will accept unauthenticated connections"
);
}
let additional_allowed_origins = allowed_origins
.into_iter()
.map(|origin| {
let origin = origin.trim();
if origin.is_empty() || origin == "*" {
anyhow::bail!("--allowed-origin must be a non-wildcard Origin value");
}
HeaderValue::from_str(origin).map_err(|error| {
anyhow::anyhow!("invalid --allowed-origin value `{origin}`: {error}")
})
})
.collect::<Result<Vec<_>>>()?;
let secret_key = env_secret.unwrap_or_else(generate_serve_secret_key);
if let Err(error) = server.start_scheduler().await {
warn!("Scheduler failed to start; scheduled jobs will not run until a client connects: {error}");
}
let router = create_router(
server,
secret_key,
require_token,
additional_allowed_origins,
);
let config = Config::global();
let tls_cert_path =
tls_cert_path.or_else(|| config.get_param::<String>("GOOSE_TLS_CERT_PATH").ok());
let tls_key_path =View on GitHub (pinned to 3810898a74)
Solutions
- Use the strict origin form scheme://host[:port] with no path, query, or trailing slash: https://app.example.com
- Fix shell quoting so no stray spaces/newlines reach the flag
- For subdomain matching do not use '*' inside the value — list each concrete subdomain origin
- If the host is non-ASCII, convert to punycode (xn--) form
Example fix
# before goose serve --allowed-origin "https://app.example.com/" goose serve --allowed-origin "https://*.example.com" # after goose serve --allowed-origin https://app.example.com goose serve --allowed-origin https://api.example.com
Defensive patterns
Strategy: validation
Validate before calling
import re
m = re.fullmatch(r"(https?)://([^/:\s]+)(:\d{1,5})?", origin.strip())
if not m:
raise SystemExit(f"not a valid origin (scheme://host[:port] only): {origin!r}") Type guard
def is_valid_origin_header(v: str) -> bool:
v = v.strip()
if not v or v == "*":
return False
try:
v.encode("ascii")
except UnicodeEncodeError:
return False
return bool(re.fullmatch(r"(https?)://[^/:\s]+(:\d{1,5})?", v)) Prevention
- Origin = scheme + host + optional port only: no path, no trailing slash
- Quote flags properly; beware newlines from command substitution
- Convert non-ASCII hosts to punycode
- No wildcards inside the value (https://*.example.com is unsupported)
When it happens
Trigger: Passing --allowed-origin values like 'http://localhost:3000/path' (origin must be scheme://host[:port] only), values with internal spaces, embedded newline/tab (unquoted shell escapes), unicode characters, or a value that is not a valid header string after the initial trim.
Common situations: Including a path or trailing slash in the origin; shell quoting bugs injecting whitespace/newlines; copying origins from a config that used wildcards like 'https://*.example.com' (invalid as a header value for this check and semantically unsupported); non-ASCII domain rendered as punycode-unconverted unicode.
Related errors
- --allowed-origin must be a non-wildcard Origin value
- GOOSE_SERVER__SECRET_KEY must be set to start `goose serve`;
- Could not resolve model config: {e}
- Could not resolve model config: {error}
- Resource '${fallbackUri}' returned no contents
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/a32da17d056552a4.
Report an issue: GitHub.