jdx/mise · error
`auth` for {key} is not `user:password`
Error message
`auth` for {key} is not `user:password` What it means
When mise reads Docker-style credentials (for `mise oci push`/registry auth) from ~/.docker/config.json, an entry's `auth` field must be base64 of `user:password`. After successful base64 decode and UTF-8 validation, the value must contain a colon; a decoded string without one (e.g. a bare API token) violates the format and fails here. Note that a valid `identitytoken` field takes precedence and bypasses this path.
Source
Thrown at src/oci/auth.rs:177
Err(e) => {
debug!("credsStore helper {helper} has no credentials for {registry}: {e}");
}
}
}
Ok(None)
}
fn credential_from_entry(entry: &AuthEntry, key: &str) -> Result<Option<Credential>> {
let (mut username, mut secret) = (entry.username.clone(), entry.password.clone());
if let Some(auth) = entry.auth.as_deref().filter(|a| !a.is_empty()) {
let decoded = BASE64_STANDARD
.decode(auth.trim())
.wrap_err_with(|| format!("decoding base64 `auth` for {key}"))?;
let decoded = String::from_utf8(decoded)
.wrap_err_with(|| format!("`auth` for {key} is not valid UTF-8"))?;
let Some((u, p)) = decoded.split_once(':') else {
bail!("`auth` for {key} is not `user:password`");
};
username = Some(u.to_string());
secret = Some(p.to_string());
}
// An identity token (docker.io "Docker Desktop" login flow) replaces the
// password; the username from `auth` is ignored by registries in this
// mode but `<token>` is the conventional placeholder.
if let Some(token) = entry.identity_token.as_deref().filter(|t| !t.is_empty()) {
return Ok(Some(Credential {
username: "<token>".to_string(),
secret: token.to_string(),
}));
}
match (username, secret) {
(Some(u), Some(p)) => Ok(Some(Credential {
username: u,
secret: p,
})),View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Re-run `docker login <server>` so a spec-conformant user:password auth entry is written
- Replace the `auth` field with explicit `"username"` and `"password"` fields in config.json
- If the secret is a registry identity token, put it in `"identitytoken"` (mise maps it to username `<token>`) instead of `auth`
- Delete the malformed entry so mise falls back to other credential sources
Example fix
# before (~/.docker/config.json)
{
"auths": {
"ghcr.io": { "auth": "Z2hwX3Rva2VuMTIzNDU2Nzg5" }
}
}
# after
{
"auths": {
"ghcr.io": {
"username": "myuser",
"password": "ghp_token123456789"
}
}
} Defensive patterns
Strategy: validation
Validate before calling
python3 - <<'EOF'
import json, base64, sys
cfg = json.load(open('$HOME/.docker/config.json'))
for key, entry in {**cfg.get('auths', {})}.items():
auth = entry.get('auth')
if auth:
try: decoded = base64.b64decode(auth).decode('utf-8')
except Exception as e: sys.exit(f'{key}: auth not base64/UTF-8: {e}')
if ':' not in decoded: sys.exit(f'{key}: auth decodes without user:password colon')
print('docker auth entries OK')
EOF Type guard
fn auth_is_user_password(auth_b64: &str) -> bool {
base64::engine::general_purpose::STANDARD
.decode(auth_b64.trim()).ok()
.and_then(|b| String::from_utf8(b).ok())
.map(|s| s.split_once(':').is_some())
.unwrap_or(false)
} Try / catch
Catch this per-server before OCI push; on trigger, skip the entry (fall back to anonymous or explicit username/password) and log which registry key needs re-login, rather than aborting the whole push.
Prevention
- Create credentials with `docker login` instead of hand-encoding base64
- Use `username`/`password` fields or `identitytoken` rather than `auth` for tokens
- Validate config.json entries with the decode-and-split check after any manual edit
When it happens
Trigger: A config.json `auth` value that base64-decodes to a token or username with no ':' separator — commonly written by third-party CLIs, cloud helpers, or manual base64 encoding of registry tokens. Hit during any OCI registry authentication when mise parses the auth entry for that server key.
Common situations: Registries whose CLI stores `echo -n <token> | base64` instead of `echo -n user:token | base64`; hand-crafted config.json entries; GitLab/GHCR deploy tokens pasted incorrectly.
Related errors
- {bin} get failed for {server}: {}
- fetching {url} failed: {}{hint} {}
- starting blob upload failed: {} {}{}
- manifest push failed: {} {url}{} {}
- push destination must be a fully-qualified reference (e.g. `
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/f2f803af38068eff.
Report an issue: GitHub.