docker/cli · error · invalidParameterErr
insecure registry should not contain '://
Error message
insecure registry %s should not contain '://'
What it means
Returned by newServiceConfig while parsing --insecure-registry entries. If an entry contains `://` the code splits off the scheme; http/https are accepted (scheme stripped with a warning), but any other scheme (ftp://, tcp://, etc.) is rejected because insecure registries must be bare host[:port] or CIDR.
Solutions
- Remove the scheme: use `--insecure-registry=myregistry:5000` instead of `ftp://myregistry:5000`.
- If you meant http(s), drop the scheme (http/https are auto-stripped with a warning).
- Re-read daemon.json and remove offending entries, then restart dockerd.
Example fix
# before dockerd --insecure-registry=tcp://registry.local:5000 # after dockerd --insecure-registry=registry.local:5000
Defensive patterns
Strategy: validation
Validate before calling
// strip any scheme before passing to InsecureRegistries
if _, _, ok := strings.Cut(entry, "://"); ok { entry = host /* or reject */ } Prevention
- Use bare host:port or CIDR for insecure registries.
- Lint daemon.json insecure-registries entries.
- Do not reuse DOCKER_HOST-style URLs here.
When it happens
Trigger: Passing an --insecure-registry value (or InsecureRegistries option) with a non-http(s) scheme, e.g. `--insecure-registry=ftp://myregistry` or `tcp://1.2.3.4:5000`.
Common situations: Copying a DOCKER_HOST-style tcp:// URL into the insecure-registry list by mistake; pasting a registry URL with a stray scheme; config management templating the wrong variable.
Related errors
- insecure registry is not valid
- error reading from STDIN: data is empty
- config file is required
- cannot supply extra formatting options to the pretty…
- unrecognized config key
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/5c76e40a7a68e0b1.
Report an issue: GitHub.
Appendix: source
Thrown at internal/registry/config.go:121
// Localhost is by default considered as an insecure registry. This is a
// stop-gap for people who are running a private registry on localhost.
registries = append(registries, "::1/128", "127.0.0.0/8")
var (
insecureRegistryCIDRs = make([]*net.IPNet, 0)
indexConfigs = make(map[string]*registry.IndexInfo)
)
skip:
for _, r := range registries {
if scheme, host, ok := strings.Cut(r, "://"); ok {
switch strings.ToLower(scheme) {
case "http", "https":
log.G(context.TODO()).Warnf("insecure registry %[1]s should not contain '%[2]s' and '%[2]ss' has been removed from the insecure registry config", r, scheme)
r = host
default:
// unsupported scheme
return nil, invalidParam(fmt.Errorf("insecure registry %s should not contain '://'", r))
}
}
// Check if CIDR was passed to --insecure-registry
_, ipnet, err := net.ParseCIDR(r)
if err == nil {
// Valid CIDR. If ipnet is already in config.InsecureRegistryCIDRs, skip.
for _, value := range insecureRegistryCIDRs {
if value.IP.String() == ipnet.IP.String() && value.Mask.String() == ipnet.Mask.String() {
continue skip
}
}
// ipnet is not found, add it in config.InsecureRegistryCIDRs
insecureRegistryCIDRs = append(insecureRegistryCIDRs, ipnet)
} else {
if err := validateHostPort(r); err != nil {
return nil, invalidParam(fmt.Errorf("insecure registry %s is not valid: %w", r, err))
}
// Assume `host:port` if not CIDR.View on GitHub (pinned to 4f84911bfe)