docker/cli · error
invalid credential spec: value must be prefixed with…
Error message
invalid credential spec: value must be prefixed with "config://", "file://", or "registry://"
What it means
The `--credential-spec` flag (Windows-only, for managed service accounts) requires a URL-scheme prefix to identify the credential source. The `credentialSpecOpt.Set` method at opts.go:362-403 parses the scheme via `strings.Cut(value, "://")` and accepts `config://`, `file://`, or `registry://`. An empty string is valid (used to clear the spec during updates, line 365-371). Any non-empty value that does not start with one of the three valid schemes hits the `default` case at line 400-402.
Solutions
- For Docker config-based specs: prefix with `config://`, e.g., `--credential-spec config://myconfig`
- For file-based specs: prefix with `file://`, e.g., `--credential-spec file://C:/path/spec.json`
- For registry-based specs: prefix with `registry://`, e.g., `--credential-spec registry://fabric/MyServiceAccount`
- To clear an existing spec on update: pass `--credential-spec ""` (empty string)
Example fix
# before docker service create --credential-spec myconfig --image myimage web # error: invalid credential spec: value must be prefixed with ... # after (Docker config) docker service create --credential-spec config://myconfig --image myimage web # after (file path) docker service create --credential-spec file://C:/spec.json --image myimage web
Defensive patterns
Strategy: validation
Validate before calling
// Validate credential spec before calling Set
func validateCredentialSpec(value string) error {
if value == "" {
return nil // empty is valid (clears spec on update)
}
scheme, _, ok := strings.Cut(value, "://")
if !ok {
return errors.New(`value must be prefixed with "config://", "file://", or "registry://"`)
}
switch credentialSpecType(scheme) {
case credentialSpecConfig, credentialSpecFile, credentialSpecRegistry:
return nil
default:
return errors.New(`invalid credential spec scheme: ` + scheme)
}
} Prevention
- Always prefix credential-spec values with config://, file://, or registry://
- Use config:// for Docker config-based specs (the config name is resolved to an ID later)
- This flag is Windows-only — verify the target platform before setting it
When it happens
Trigger: Passing `--credential-spec myconfig` (no scheme), `--credential-spec C:\path\to\spec.json` (bare file path without `file://` prefix), or `--credential-spec configs/myconfig` (Docker config name without `config://` prefix).
Common situations: A Windows shop migrating from `docker run --credential-spec` confuses the flag value format. The developer passes the config name or file path directly without the required URL scheme prefix.
Related errors
- placement preference must be of the format
- replicas can only be used with replicated or replicated-job…
- replicas-max-per-node can only be used with replicated or…
- max-concurrent can only be used with replicated-job mode
- update and rollback configuration is not supported for jobs
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/434314a7389a98b2.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/service/opts.go:402
// Therefore, this isn't the definitive location for the value of
// Config that is passed to the API.
c.value = &swarm.CredentialSpec{
Config: val,
}
return nil
case credentialSpecFile:
c.value = &swarm.CredentialSpec{
File: val,
}
return nil
case credentialSpecRegistry:
c.value = &swarm.CredentialSpec{
Registry: val,
}
return nil
default:
c.value = &swarm.CredentialSpec{}
return errors.New(`invalid credential spec: value must be prefixed with "config://", "file://", or "registry://"`)
}
}
func (*credentialSpecOpt) Type() string {
return "credential-spec"
}
func (c *credentialSpecOpt) String() string {
return c.source
}
func (c *credentialSpecOpt) Value() *swarm.CredentialSpec {
return c.value
}
func resolveNetworkID(ctx context.Context, apiClient client.NetworkAPIClient, networkIDOrName string) (string, error) {
res, err := apiClient.NetworkInspect(ctx, networkIDOrName, client.NetworkInspectOptions{Scope: "swarm"})
if err != nil {View on GitHub (pinned to 4f84911bfe)