{"record":{"id":"4c61661626f68300","repo":"NginxProxyManager/nginx-proxy-manager","slug":"unknown-dns-provider-certificate-meta-dns-provi","errorCode":null,"errorMessage":"Unknown DNS provider '${certificate.meta.dns_provider}'","messagePattern":"Unknown DNS provider '(.+?)'","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"backend/internal/certificate.js","lineNumber":977,"sourceCode":"\n\t\tconst adds = internalCertificate.getAdditionalCertbotArgs(certificate.id, certificate.meta.dns_provider);\n\t\targs.push(...adds.args);\n\n\t\tlogger.info(`Command: ${certbotCommand} ${args ? args.join(\" \") : \"\"}`);\n\n\t\tconst result = await utils.execFile(certbotCommand, args, adds.opts);\n\t\tlogger.info(result);\n\t\treturn result;\n\t},\n\n\t/**\n\t * @param   {Object}  certificate   the certificate row\n\t * @returns {Promise}\n\t */\n\trenewLetsEncryptSslWithDnsChallenge: async (certificate) => {\n\t\tconst dnsPlugin = dnsPlugins[certificate.meta.dns_provider];\n\t\tif (!dnsPlugin) {\n\t\t\tthrow Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`);\n\t\t}\n\n\t\tlogger.info(\n\t\t\t`Renewing LetsEncrypt certificates via ${dnsPlugin.name} for Cert #${certificate.id}: ${certificate.domain_names.join(\", \")}`,\n\t\t);\n\n\t\tconst args = [\n\t\t\t\"renew\",\n\t\t\t\"--force-renewal\",\n\t\t\t\"--config\",\n\t\t\tletsencryptConfig,\n\t\t\t\"--work-dir\",\n\t\t\tcertbotWorkDir,\n\t\t\t\"--logs-dir\",\n\t\t\tcertbotLogsDir,\n\t\t\t\"--cert-name\",\n\t\t\t`npm-${certificate.id}`,\n\t\t\t\"--preferred-challenges\",","sourceCodeStart":959,"sourceCodeEnd":995,"githubUrl":"https://github.com/NginxProxyManager/nginx-proxy-manager/blob/934a3fafe5ae82d752f0a18c0f1d0eb050296730/backend/internal/certificate.js#L959-L995","documentation":"During automated renewal of a Let's Encrypt certificate via DNS-01 challenge, internal/certificate.js looks up certificate.meta.dns_provider in the dnsPlugins registry. If the provider slug stored in the certificate metadata has no matching plugin entry, renewal aborts with this Error before contacting Let's Encrypt.","triggerScenarios":"A certificate was created with a dns_provider value that the current build no longer (or never did) recognize — e.g. metadata says 'route53' but dnsPlugins lacks that key, custom/misspelled provider names inserted via API, or certificates created on an older NPM version being renewed after an upgrade/downgrade that changed the dns-plugins list.","commonSituations":"NPM version changes that renamed or removed DNS providers, certificates migrated between instances with different plugin sets, manually edited certificate rows in the database, or renewal jobs (cron) failing repeatedly and silently because the stored metadata is bad.","solutions":["Inspect the certificate row (GET /api/nginx/certificates/:id) and compare meta.dns_provider against the keys in backend/internal/dns-plugins.js of the running version","If it's a typo/rename, recreate the certificate via the UI/API with the correct provider slug (metadata is not safely editable in place)","If the provider legitimately doesn't exist in your build, upgrade NPM to a version that supports the provider, or re-issue the certificate using a supported provider or HTTP challenge","As a stopgap for a custom build, add the provider entry to dns-plugins and rebuild the container"],"exampleFix":"// before: certificate.meta = { dns_provider: 'aws' } // not a registered slug\nError(\"Unknown DNS provider 'aws'\")\n\n// after: recreate cert with a registered slug, e.g.\n// POST /api/nginx/certificates\n{\n  \"provider\": \"letsencrypt\",\n  \"domain_names\": [\"example.com\"],\n  \"meta\": { \"dns_provider\": \"digitalocean\", \"dns_provider_credentials\": \"...\" }\n}","handlingStrategy":"validation","validationCode":"import dnsPlugins from './internal/dns-plugins.js';\n\nconst providerSupported = (provider: string) =>\n  Object.prototype.hasOwnProperty.call(dnsPlugins, provider);\n\n// before triggering renewal:\nif (!providerSupported(certificate.meta.dns_provider)) {\n  logger.warn(`Cert #${certificate.id}: provider '${certificate.meta.dns_provider}' unsupported; skipping renewal`);\n  return;\n}","typeGuard":"const isSupportedDnsProvider = (name: unknown): name is keyof typeof dnsPlugins =>\n  typeof name === 'string' && Object.prototype.hasOwnProperty.call(dnsPlugins, name);","tryCatchPattern":"try {\n  await internalCertificate.renewLetsEncryptSslWithDnsChallenge(certificate);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Unknown DNS provider')) {\n    // mark cert for re-creation with a valid provider; alert the owner, do not blind-retry\n  }\n  throw e;\n}","preventionTips":["Validate meta.dns_provider against the plugin registry at certificate creation time, not renewal time","Run a pre-upgrade check that all stored certificates' dns_provider values exist in the new version's dns-plugins.js","Monitor renewal logs for this message and recreate affected certificates promptly instead of letting them expire"],"tags":["nginx-proxy-manager","dns-challenge","lets-encrypt","certificate-renewal","config-metadata"],"backgroundTag":"unknown-dns-provider","analyzedSha":"934a3fafe5ae82d752f0a18c0f1d0eb050296730","analyzedAt":"2026-08-27T14:34:22.258Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}