Skip to content

DefaultProductCode: not used for new enrollments, but used unconditionally (with no per-template override) for renewals #26

Description

@spbsoluble

Symptom

DefaultProductCode's actual behavior is split, and doesn't match what its own UI text/docs described (a generic "fallback when no template code is set"):

  • New enrollments: never consulted. Models/EnrollmentParams.cs's ProductCode getter falls back only to a built-in default keyed by product name, never to _config.DefaultProductCode. Client/CERTInextClient.cs's BuildOrderRequestFromLegacyEnrollRequest has ProductCode = request.ProfileId ?? _config.DefaultProductCode ?? string.Empty, but request.ProfileId is never null (worst case ""), so that fallback is unreachable.
  • Renewals: consulted unconditionally. RenewCertificateAsync (CERTInextClient.cs:820) sets ProductCode = _config.DefaultProductCode ?? string.Empty with no other fallback — the code comment notes "we don't have the product code from TrackOrder." This ignores the template's ProductCode/ProfileId entirely for renewals. If DefaultProductCode is left unset (its default is "", not null), every renewal is submitted with an empty product code.

How this was found

Found during a docsource freshness review (2026-08-13). Originally filed (incorrectly) as "dead code with no effect anywhere" — a follow-up verification pass caught that the renewal path does use it, unconditionally. Docs (docsource/configuration.md) have been corrected to describe the actual split behavior.

Severity

Medium — for any deployment that renews certificates and hasn't set DefaultProductCode, renewals may be going out with an empty product code today. Worth checking whether this has caused silent renewal failures.

Fix

Not fixed here. Options: make the renewal path respect the template's ProductCode/ProfileId (probably the right fix, if that information is available to the renewal call), or at minimum validate DefaultProductCode is set before attempting a renewal and fail clearly instead of submitting an empty code.

Files

  • CERTInext/Client/CERTInextClient.cs:820 (RenewCertificateAsync)
  • CERTInext/Models/EnrollmentParams.cs (ProductCode getter — new-enrollment path, unaffected)
  • docsource/configuration.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions