{"record":{"id":"4b083ec5a7004406","repo":"Dokploy/dokploy","slug":"sanitizeregistryerror-execerror-response-passw","errorCode":null,"errorMessage":"${sanitizeRegistryError(execError, response?.password)}","messagePattern":"\\$\\{sanitizeRegistryError\\(execError, response\\?\\.password\\)\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/server/src/services/registry.ts","lineNumber":154,"sourceCode":"\t\tif (\n\t\t\tIS_CLOUD &&\n\t\t\t!registryData?.serverId &&\n\t\t\tregistryData?.serverId !== \"none\"\n\t\t) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: \"NOT_FOUND\",\n\t\t\t\tmessage: \"Select a server to add the registry\",\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\tif (registryData?.serverId && registryData?.serverId !== \"none\") {\n\t\t\t\tawait execAsyncRemote(registryData.serverId, loginCommand);\n\t\t\t} else if (response?.registryType === \"cloud\") {\n\t\t\t\tawait execAsync(loginCommand);\n\t\t\t}\n\t\t} catch (execError) {\n\t\t\tthrow new Error(sanitizeRegistryError(execError, response?.password));\n\t\t}\n\n\t\treturn response;\n\t} catch (error) {\n\t\tconst message =\n\t\t\terror instanceof TRPCError\n\t\t\t\t? error.message\n\t\t\t\t: error instanceof Error\n\t\t\t\t\t? error.message\n\t\t\t\t\t: \"Error updating this registry\";\n\t\tthrow new TRPCError({\n\t\t\tcode: \"BAD_REQUEST\",\n\t\t\tmessage,\n\t\t});\n\t}\n};\n\nexport const findRegistryById = async (registryId: string) => {","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/Dokploy/dokploy/blob/546686ea3587f12ec5652217dedd9f7960fb6d15/packages/server/src/services/registry.ts#L136-L172","documentation":"Inside updateRegistry, after the DB update a docker login is re-executed with the stored/updated credentials (execAsyncRemote for a bound server, execAsync for cloud-type registries). If the login command fails, a plain Error is thrown whose message is the sanitized docker error (password masked with ***). This inner Error is then caught by the outer catch and re-wrapped as a BAD_REQUEST TRPCError with the same message — so the message you ultimately see IS this sanitized docker output.","triggerScenarios":"Updating a registry with new credentials that are wrong/expired, the registry being unreachable, or the bound remote server being offline at update time.","commonSituations":"Rotated registry tokens not updated in Dokploy, typo in the new password, remote server down when the automatic re-login runs after an update.","solutions":["Reproduce manually: echo <password> | docker login <registryUrl> -u <username> --password-stdin on the target server","Fix/regenerate the credentials and retry the update","Verify the remote server is reachable if serverId is set"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"# verify the new credentials before updating\necho \"$NEW_PASSWORD\" | docker login <registryUrl> -u \"$USER\" --password-stdin","typeGuard":"const isLoginFailure = (e: unknown): e is TRPCError =>\n  e instanceof TRPCError && e.code === \"BAD_REQUEST\" && /password|unauthorized|login/i.test(e.message);","tryCatchPattern":"try { await updateRegistry(registryId, data); } catch (e) { if (isLoginFailure(e)) { /* message is sanitized docker stderr; fix creds */ } throw e; }","preventionTips":["Validate credentials with a manual docker login before saving updates","Note the DB row IS updated even though login failed — re-save after fixing creds"],"tags":["dokploy","registry","docker-login","credentials","update"],"backgroundTag":"docker-login-failed","analyzedSha":"546686ea3587f12ec5652217dedd9f7960fb6d15","analyzedAt":"2026-08-27T05:18:58.095Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}