JuliusBrussee/caveman · error
awscreds: AWS_EC2_METADATA_SERVICE_ENDPOINT is not a valid…
Error message
awscreds: AWS_EC2_METADATA_SERVICE_ENDPOINT is not a valid URL
What it means
checkIMDSEndpoint validates AWS_EC2_METADATA_SERVICE_ENDPOINT: it must parse as a URL with a non-empty host, and be https or http to loopback/link-local IMDS addresses. This guard exists because the variable was previously dialed verbatim by the proxy-ignoring IMDS client, so any host named there became a proxy-bypassing request carrying the IMDSv2 token. A value that fails to parse or has an empty host yields this error.
Solutions
- Set AWS_EC2_METADATA_SERVICE_ENDPOINT to a full URL including scheme and host, e.g. http://169.254.169.254/latest or https://custom-endpoint
- Check shell/export quoting so the value is not truncated or space-split
- Remove the variable entirely to use the default IMDS endpoint
Example fix
// before export AWS_EC2_METADATA_SERVICE_ENDPOINT=169.254.169.254 // after export AWS_EC2_METADATA_SERVICE_ENDPOINT=http://169.254.169.254
Defensive patterns
Strategy: validation
Validate before calling
func imdsEndpointIsValid(raw string) bool {
u, err := url.Parse(raw)
if err != nil || u.Host == "" { return false }
if u.Scheme == "https" { return true }
if u.Scheme == "http" {
h := u.Hostname()
return h == "169.254.169.254" || h == "fd00:ec2::254" || h == "localhost" || strings.HasPrefix(h, "127.")
}
return false
}
Try / catch
if ep := os.Getenv("AWS_EC2_METADATA_SERVICE_ENDPOINT"); ep != "" {
if err := awscreds.CheckIMDSEndpoint(ep); err != nil {
// unset or correct the variable before credential resolution
}
}
Prevention
- Always include scheme and host in the endpoint value
- Omit the variable to use the default IMDS endpoint
- Validate env values in a startup check before relying on them
When it happens
Trigger: fromIMDS runs while AWS_EC2_METADATA_SERVICE_ENDPOINT is unset-but-nonempty-garbage, contains only a scheme with no host ('http://'), or otherwise fails url.Parse.
Common situations: Setting the endpoint to a bare hostname without scheme, truncated env values from misquoted shell exports, or an endpoint config written as '169.254.169.254' instead of 'http://169.254.169.254'.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- awscreds: refusing plaintext IMDS endpoint at host
- awscreds: AWS_CONTAINER_CREDENTIALS_FULL_URI is not a valid…
- awscreds: build imds token request
- awscreds: build request
- awscreds: no AWS credentials found (env, web identity…
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/3cd8a3e00d3ee905.
Report an issue: GitHub.
Appendix: source
Thrown at shared/platform/awscreds/awscreds.go:522
return nil
case "http":
if plaintextHostAllowed(u.Hostname(), containerCredentialHosts) {
return nil
}
return fmt.Errorf("awscreds: refusing plaintext container credentials endpoint at host %q (allowed: loopback, 169.254.170.2, 169.254.170.23, fd00:ec2::23)", u.Hostname())
default:
return fmt.Errorf("awscreds: unsupported container credentials scheme %q", u.Scheme)
}
}
// checkIMDSEndpoint is checkContainerURI for AWS_EC2_METADATA_SERVICE_ENDPOINT.
// That variable was taken verbatim and then dialled with p.link — the client
// that deliberately ignores every proxy setting — so any host named there became
// a proxy-bypassing outbound request with the IMDSv2 token attached.
func checkIMDSEndpoint(raw string) error {
u, err := url.Parse(raw)
if err != nil || u.Host == "" {
return errors.New("awscreds: AWS_EC2_METADATA_SERVICE_ENDPOINT is not a valid URL")
}
switch u.Scheme {
case "https":
return nil
case "http":
if plaintextHostAllowed(u.Hostname(), imdsHosts) {
return nil
}
return fmt.Errorf("awscreds: refusing plaintext IMDS endpoint at host %q (allowed: loopback, 169.254.169.254, fd00:ec2::254)", u.Hostname())
default:
return fmt.Errorf("awscreds: unsupported IMDS endpoint scheme %q", u.Scheme)
}
}
func (p *Provider) fromIMDS(ctx context.Context) (*result, error) {
if strings.EqualFold(p.env("AWS_EC2_METADATA_DISABLED"), "true") {
return nil, nil
}View on GitHub (pinned to 3ee70a1026)