JuliusBrussee/caveman · error

awscreds: AWS_CONTAINER_CREDENTIALS_FULL_URI is not a valid…

Error message

awscreds: AWS_CONTAINER_CREDENTIALS_FULL_URI is not a valid URL

What it means

checkContainerURI validates AWS_CONTAINER_CREDENTIALS_FULL_URI before it is ever dialed: it must parse as a URL and be either https, or http pointed at loopback or the fixed ECS/EKS credential endpoints (169.254.170.2 / 169.254.170.23). This prevents handing a task role's Authorization token to an arbitrary attacker-controlled host. A value that does not parse as a URL yields this error.

Solutions

  1. Fix AWS_CONTAINER_CREDENTIALS_FULL_URI to a syntactically valid absolute URL (e.g. http://169.254.170.2/v2/credentials or an https:// endpoint)
  2. Check the task definition / env injection for quoting or whitespace issues corrupting the value
  3. Prefer the relative variant AWS_CONTAINER_CREDENTIALS_RELATIVE_URI on ECS, which avoids full-URL validation entirely

Example fix

// before
export AWS_CONTAINER_CREDENTIALS_FULL_URI="http://169.254.170.2 /v2/credentials"
// after
export AWS_CONTAINER_CREDENTIALS_FULL_URI="http://169.254.170.2/v2/credentials"
Defensive patterns

Strategy: validation

Validate before calling

func containerURIIsSafe(raw string) bool {
	u, err := url.Parse(raw)
	if err != nil { return false }
	if u.Scheme == "https" { return true }
	if u.Scheme == "http" {
		h := u.Hostname()
		return h == "169.254.170.2" || h == "169.254.170.23" || h == "localhost" || strings.HasPrefix(h, "127.")
	}
	return false
}

Try / catch

if err := awscreds.CheckContainerURI(os.Getenv("AWS_CONTAINER_CREDENTIALS_FULL_URI")); err != nil {
	// fix env before starting the provider
}

Prevention

When it happens

Trigger: fromContainer runs and AWS_CONTAINER_CREDENTIALS_FULL_URI contains a string url.Parse rejects — control characters, stray spaces, or a malformed scheme like 'htp://...' or '%zz'.

Common situations: Typoed scheme in an ECS/EKS task definition env var, quoting bugs injecting whitespace into the env value, or copying an example endpoint with a trailing character.

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


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/61baa6b9c526261a. Report an issue: GitHub.

Appendix: source

Thrown at shared/platform/awscreds/awscreds.go:500

		return true
	}
	addr = addr.Unmap()
	for _, allowed := range allow {
		if addr == allowed {
			return true
		}
	}
	return false
}

// checkContainerURI applies the SDK rule for a caller-supplied credential
// endpoint: TLS anywhere, plaintext only to loopback or the fixed ECS/EKS
// credential addresses. Without it, AWS_CONTAINER_CREDENTIALS_FULL_URI is a
// request to hand a task role's Authorization token to an arbitrary host.
func checkContainerURI(raw string) error {
	u, err := url.Parse(raw)
	if err != nil {
		return errors.New("awscreds: AWS_CONTAINER_CREDENTIALS_FULL_URI is not a valid URL")
	}
	switch u.Scheme {
	case "https":
		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.

View on GitHub (pinned to 3ee70a1026)