{"record":{"id":"87d77f5b0d8d58f1","repo":"goharbor/harbor","slug":"tencent-tcr-newadapter-please-use-secretid-secre","errorCode":null,"errorMessage":"[tencent-tcr.newAdapter] Please use SecretId/SecretKey, NOT docker login Username/Password","messagePattern":"\\[tencent-tcr\\.newAdapter\\] Please use SecretId/SecretKey, NOT docker login Username/Password","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/pkg/reg/adapter/tencentcr/adapter.go","lineNumber":100,"sourceCode":"\ntype adapter struct {\n\t*native.Adapter\n\tregistryID *string\n\tregionName *string\n\ttcrClient  *tcr.Client\n\tpageSize   *int64\n\tclient     *commonhttp.Client\n\tregistry   *model.Registry\n}\n\n/**\n\t* Implement Adapter Interface\n**/\nvar _ adp.Adapter = &adapter{}\n\nfunc newAdapter(registry *model.Registry) (a *adapter, err error) {\n\tif !isSecretID(registry.Credential.AccessKey) {\n\t\terr = errors.New(\"[tencent-tcr.newAdapter] Please use SecretId/SecretKey, NOT docker login Username/Password\")\n\t\tlog.Debugf(\"[tencent-tcr.newAdapter] error=%v\", err)\n\t\treturn\n\t}\n\n\t// Query TCR instance info via endpoint.\n\tvar registryURL *url.URL\n\tregistryURL, _ = url.Parse(registry.URL)\n\n\t// only validate registryURL.Host in non-UT scenario\n\tif os.Getenv(\"UTTEST\") != \"true\" {\n\t\tif !strings.Contains(registryURL.Host, \".tencentcloudcr.com\") {\n\t\t\tlog.Errorf(\"[tencent-tcr.newAdapter] errInvalidTcrEndpoint=%v\", err)\n\t\t\treturn nil, errInvalidTcrEndpoint\n\t\t}\n\t}\n\n\trealm, service, err := util.Ping(registry)\n\tlog.Debugf(\"[tencent-tcr.newAdapter] realm=%s, service=%s error=%v\", realm, service, err)","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/pkg/reg/adapter/tencentcr/adapter.go#L82-L118","documentation":"Returned by newAdapter for the Tencent TCR adapter (src/pkg/reg/adapter/tencentcr/adapter.go:100) when registry.Credential.AccessKey does not look like a Tencent Cloud SecretId: isSecretID (src/pkg/reg/adapter/tencentcr/auth.go:98) requires the key to start with 'AKID' or 'IKID'. The adapter needs the SecretId/SecretKey pair to call the Tencent Cloud API (temporary docker-login tokens are generated from it), so docker login credentials are rejected up front.","triggerScenarios":"Creating a tencentcr adapter with Credential.AccessKey set to a docker login username (e.g. the TCR temporary username from 'docker login', or a random user) instead of a Tencent Cloud API SecretId. Any key not prefixed AKID/IKID triggers it, including an empty AccessKey.","commonSituations":"Users pasting the temporary username/password printed by the TCR console 'Generate login command' into the endpoint credential fields; using CAM-role assumed credentials without the SecretId prefix; leaving credentials empty because docker pull worked anonymously; switching from the docker-hub adapter where username/password is correct.","solutions":["Create a Tencent Cloud API key pair (CAM > Access Keys) and use the SecretId (starts with AKID) as AccessKey and the SecretKey as AccessSecret.","If a temporary docker login credential is all you have, generate it from the console/API with your SecretId/SecretKey — do not feed the temp username into this adapter.","Verify the credential shape before creating the adapter (see validationCode for a prefix check).","Grant the CAM user QcloudTCRFullAccess or scoped TCR permissions so subsequent API calls succeed."],"exampleFix":"// before\nregistry.Credential = &model.Credential{\n    AccessKey:   \"temp-username-1600000000\",  // docker login temp username\n    AccessSecret: \"temp-password\",\n}\n\n// after\nregistry.Credential = &model.Credential{\n    AccessKey:   \"AKIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\", // SecretId\n    AccessSecret: \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",    // SecretKey\n}","handlingStrategy":"validation","validationCode":"func looksLikeSecretID(key string) bool {\n\treturn strings.HasPrefix(key, \"AKID\") || strings.HasPrefix(key, \"IKID\")\n}\nif !looksLikeSecretID(registry.Credential.AccessKey) {\n\treturn fmt.Errorf(\"provide Tencent Cloud SecretId/SecretKey, not docker login credentials\")\n}","typeGuard":"func isTencentSecretCredential(c *model.Credential) bool {\n\treturn c != nil && (strings.HasPrefix(c.AccessKey, \"AKID\") || strings.HasPrefix(c.AccessKey, \"IKID\"))\n}","tryCatchPattern":"a, err := tencentcr.NewAdapter(registry)\nif err != nil {\n\tif strings.Contains(err.Error(), \"Please use SecretId/SecretKey\") {\n\t\t// credential config error: switch to a Tencent Cloud API key pair\n\t}\n\treturn nil, err\n}","preventionTips":["Create the credential in CAM (Access Keys), not from the console 'docker login' temp command.","SecretId values start with AKID (or IKID for some accounts) — use that as a sanity check before saving the endpoint.","Grant the key TCR permissions so later API calls succeed.","Store the SecretKey via a secret manager, never in plaintext config."],"tags":["go","tencent-tcr","tencentcloud","credentials","configuration"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}