goharbor/harbor · error
missing custom token/key data
Error message
missing custom token/key data
What it means
CustomAuthHandler.Authorize rejects a preheat request when the provider instance uses CUSTOM auth mode but the credential data map is empty — there is no header name/value to set. As with the basic handler, it takes the FIRST key of the map as the HTTP header name and its value as the header value.
Solutions
- Re-save the instance with auth_info containing the header name as key and the token as value: {"auth_mode": "CUSTOM", "auth_info": {"X-API-Key": "abc123"}}.
- Ensure exactly the intended single entry, since only the first map key is used.
- If the provider truly needs no auth, use auth_mode "NONE".
Example fix
# before
curl -X POST https://harbor/api/v2.0/p2p/preheat/instances -d '{"name": "kraken", "provider": "kraken", "endpoint": "https://kraken.example.com", "auth_mode": "CUSTOM", "auth_info": {}}'
# after
curl -X POST https://harbor/api/v2.0/p2p/preheat/instances -d '{"name": "kraken", "provider": "kraken", "endpoint": "https://kraken.example.com", "auth_mode": "CUSTOM", "auth_info": {"X-API-Key": "abc123"}}' Defensive patterns
Strategy: validation
Validate before calling
function validateCustomAuthInfo(authInfo) {
const entries = Object.entries(authInfo || {});
if (entries.length !== 1) throw new Error('CUSTOM auth requires exactly one {headerName: headerValue} entry');
const [k, v] = entries[0];
if (!/^X-[A-Za-z-]+$|^Authorization$/.test(k) || !v) throw new Error('invalid header key/value');
} Type guard
function isCustomCredValid(cred) {
return cred != null && cred.Data != null && Object.keys(cred.Data).length > 0;
} Try / catch
On 'missing custom token/key data', fix the instance's auth_info to a single {headerName: value} entry via PUT, then trigger a fresh policy execution. Prevention
- CUSTOM auth = one map entry: key is the header name (e.g. X-API-Key), value is the header value.
- Send auth_info as a JSON object, never a string.
- Add schema validation for provider instance payloads in IaC.
When it happens
Trigger: A preheat instance registered with auth_mode "CUSTOM" and empty/missing auth_info; auth_info present but not deserializing into map[string]string; any policy execution against that instance fails at the first authorized request.
Common situations: Providers secured by a static API-key header (e.g. X-API-Key) where the key was never entered; storing auth_info as "X-API-Key: abc" (a string) instead of an object; instance updated later and auth_info wiped.
Related errors
- missing username and/or password
- missing OAuth token
- no credential data provided
- BAD_REQUEST
- Unauthorized
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/519c893b1714af38.
Report an issue: GitHub.
Appendix: source
Thrown at src/pkg/p2p/preheat/provider/auth/custom_handler.go:40
// CustomAuthHandler handle the custom auth mode.
type CustomAuthHandler struct {
*BaseHandler
}
// Mode implements @Handler.Mode
func (c *CustomAuthHandler) Mode() string {
return AuthModeCustom
}
// Authorize implements @Handler.Authorize
func (c *CustomAuthHandler) Authorize(req *http.Request, cred *Credential) error {
if err := c.BaseHandler.Authorize(req, cred); err != nil {
return err
}
if len(cred.Data) == 0 {
return errors.New("missing custom token/key data")
}
key := reflect.ValueOf(cred.Data).MapKeys()[0].String()
req.Header.Set(key, cred.Data[key])
return nil
}
View on GitHub (pinned to 7b2fd08cc5)