certz renew -- Reference

May 2, 2026 ยท View on GitHub

Extend the validity of an existing certificate without re-entering its parameters. certz reads the source certificate, preserves its subject, SANs, and key type, then issues a new certificate with a fresh validity window.

See also: Certificate Lifecycle | RSA vs ECDSA | Exit Codes


What Renewal Does

certz renew is a one-command alternative to the full create-inspect-trust cycle when you only need to extend a certificate's expiry date. It:

  1. Reads the existing certificate from the PFX (or certificate store)
  2. Extracts the subject DN, SANs, and key type
  3. Generates a new key pair (unless --keep-key is used)
  4. Issues a new certificate with the same identity but a new validity period
  5. Writes the renewed certificate to the output file

Self-signed certificates renew without any extra flags. CA-signed certificates require --issuer-cert because certz cannot automatically locate the issuer.


What Is Preserved vs What You Can Override

ParameterPreserved automaticallyOverride flag
Subject (CN, O, OU, C, etc.)YesNot currently overridable
Subject Alternative NamesYes -- copied verbatim by default--add-san <value> and --remove-san <value> (both repeatable)
Key type (ECDSA P-256, RSA, etc.)YesNot currently overridable
Private key itselfNo -- new key generated--keep-key reuses existing key
Validity periodNo -- specify new period--days (default: 90, max: 398)
IssuerNo -- must be provided for CA-signed--issuer-cert + --issuer-password
Output file pathNo -- defaults to <original>-renewed.pfx--out
Output passwordNo -- auto-generated--out-password

Before/After: Self-Signed Renewal

Before:

Subject:    CN=api.company.com
Issuer:     CN=api.company.com (self-signed)
SANs:       api.company.com, localhost, 127.0.0.1
Key:        ECDSA P-256
Not Before: 2025-08-01 00:00:00 UTC
Not After:  2025-10-29 00:00:00 UTC    <- expires in 3 days
Thumbprint: A1B2C3D4E5F6...

Renewal command:

certz renew api.pfx --password MyPassword --days 90

After:

Subject:    CN=api.company.com          <- unchanged
Issuer:     CN=api.company.com          <- unchanged
SANs:       api.company.com, localhost, 127.0.0.1  <- unchanged
Key:        ECDSA P-256                 <- unchanged
Not Before: 2025-10-26 00:00:00 UTC    <- new (today)
Not After:  2026-01-23 00:00:00 UTC    <- new (90 days from now)
Thumbprint: B3C4D5E6F7A8...            <- different -- this is a new certificate

Only the validity window and thumbprint change. Everything else is carried forward.


Before/After: CA-Signed Renewal

When the original certificate was signed by a CA, you must supply the issuer on renewal. certz cannot auto-locate the CA from the certificate alone.

Before:

Subject:    CN=api.company.com
Issuer:     CN=Dev CA                  <- CA-signed, not self-signed
SANs:       api.company.com, localhost, 127.0.0.1
Key:        ECDSA P-256
Not Before: 2025-08-01 00:00:00 UTC
Not After:  2025-10-29 00:00:00 UTC    <- expires in 3 days

Renewal command:

certz renew server.pfx --password ServerPass \
  --issuer-cert ca.pfx --issuer-password CaPass \
  --days 90

After:

Subject:    CN=api.company.com          <- unchanged
Issuer:     CN=Dev CA                  <- unchanged (re-signed by same CA)
SANs:       api.company.com, localhost, 127.0.0.1  <- unchanged
Key:        ECDSA P-256                 <- unchanged
Not Before: 2025-10-26 00:00:00 UTC    <- new
Not After:  2026-01-23 00:00:00 UTC    <- new
Thumbprint: C4D5E6F7A8B9...            <- different

The renewed certificate is signed by the same CA. The chain of trust is maintained -- clients that already trust the CA will trust the renewed cert without any store changes.


Key Reuse with --keep-key

By default, certz generates a fresh key pair on every renewal. Use --keep-key to reuse the original private key.

# Generate new key (default -- recommended for scheduled rotation)
certz renew server.pfx --password MyPassword --days 90

# Reuse existing key
certz renew server.pfx --password MyPassword --days 90 --keep-key

When to reuse the key (--keep-key):

  • You have distributed or pinned the public key in dependent systems
  • Minimal disruption is required -- no re-distribution of the key needed

When to generate a new key (default):

  • Scheduled key rotation policy
  • Suspected compromise of the private key
  • You want a clean rotation with a fresh key

Security note: Reusing a key means a compromised private key stays compromised across renewals. Unless you have a specific reason to pin the key, generating a new one on each renewal is the safer default.


Modifying SANs During Renewal

By default, the SAN list is carried forward verbatim. Use --add-san and --remove-san (both repeatable) to adjust the list as part of the renewal.

# Add a new hostname while renewing
certz renew api.pfx --password Pass --add-san api-v2.local

# Remove a retired hostname and add a replacement
certz renew api.pfx --password Pass --remove-san old.local --add-san new.local

# Combine multiple values
certz renew api.pfx --password Pass \
  --remove-san legacy.local \
  --add-san api-v2.local --add-san 10.0.0.5

Validation rules (applied to the merged result before the new certificate is created):

  • BR-019 -- --add-san values must not contain whitespace.
  • BR-020 -- the merged SAN list must not contain entries longer than 253 chars or labels longer than 63 chars.
  • BR-021 -- dnsName entries must follow RFC 1035 preferred-name-syntax (LDH characters, no leading/trailing hyphens; wildcard exempt).
  • BR-023 -- adding a value that already exists in the SAN list (case-insensitive) is rejected.

IP literals in --add-san (e.g. 10.0.0.5, ::1) are auto-routed to the iPAddress SAN entry rather than dnsName, which keeps the result compliant with RFC 6125 sec 6.4.

Source-side duplicates (latent duplicates from older certs) are silently collapsed when you actively edit SANs, so a renewal with --add-san/--remove-san produces a clean list even if the original cert had duplicate entries.


Full Options

OptionDefaultDescription
<source>(required)PFX file path or certificate store thumbprint to renew.
--password, -p(none)Password for the source PFX. Also reads from CERTZ_PASSWORD env var.
--days90New validity period in days. Maximum 398.
--keep-keyfalseReuse the existing private key instead of generating a new one.
--issuer-cert(none)CA certificate file. Required if the original cert was CA-signed.
--issuer-key(none)CA private key file. Required when --issuer-cert is a PEM without embedded key.
--issuer-password(none)Password for a PFX --issuer-cert.
--out, -o<original>-renewed.pfxOutput file path for the renewed certificate.
--out-password(auto-generated)Password for the output PFX. Printed to console when auto-generated.
--store(none)Certificate store name for thumbprint-based lookup: My, Root, CA.
--location, -lCurrentUserStore location: CurrentUser or LocalMachine.
--add-san(none)Add a SAN value (dnsName or IP literal) to the renewed certificate. Repeatable. Validated against BR-019..BR-023. IP literals are routed to iPAddress entries.
--remove-san(none)Remove a SAN value from the existing list. Repeatable. Match is case-insensitive.
--dry-run, --drfalseLoad source cert, show what parameters would be preserved and the new expiry, without writing any output.
--formattextOutput format: text or json.
--guidedfalseLaunch the interactive wizard for renew. Prompts for source, days, key reuse, optional SAN edits, and issuer.

JSON Output Schema

certz renew server.pfx --password MyPassword --format json

Example output:

{
  "success": true,
  "errorMessage": null,
  "originalSubject": "CN=api.company.com",
  "originalThumbprint": "A1B2C3D4E5F6...",
  "originalNotAfter": "2025-10-29T00:00:00Z",
  "newSubject": "CN=api.company.com",
  "newThumbprint": "B3C4D5E6F7A8...",
  "newNotBefore": "2025-10-26T00:00:00Z",
  "newNotAfter": "2026-01-23T00:00:00Z",
  "outputFile": "api-renewed.pfx",
  "password": "Xk9!mP2rLq",
  "passwordWasGenerated": true,
  "sans": ["api.company.com", "localhost", "127.0.0.1"],
  "keyType": "ECDSA-P256",
  "keyWasPreserved": false,
  "wasResigned": false
}
FieldTypeDescription
successbooltrue if renewal completed without errors
errorMessagestring or nullError description if success is false
originalSubjectstringSubject DN before renewal
originalThumbprintstringSHA-1 thumbprint of the original certificate
originalNotAfterISO 8601Expiry of the original certificate (UTC)
newSubjectstring or nullSubject DN of the renewed certificate (same as original)
newThumbprintstring or nullSHA-1 thumbprint of the renewed certificate
newNotBeforeISO 8601 or nullValidity start of the renewed certificate (UTC)
newNotAfterISO 8601 or nullExpiry of the renewed certificate (UTC)
outputFilestring or nullPath to the output PFX file
passwordstring or nullOutput PFX password (only present when auto-generated)
passwordWasGeneratedbooltrue when certz chose the output password
sansstring[] or nullSubject Alternative Names carried forward from the original
keyTypestring or nullKey algorithm: ECDSA-P256, ECDSA-P384, ECDSA-P521, or RSA
keyWasPreservedbooltrue when --keep-key was used
wasResignedbooltrue when --issuer-cert was provided and used for signing

Troubleshooting

ProblemLikely causeFix
"Issuer not provided" errorCA-signed cert renewed without --issuer-certcertz cannot auto-locate the issuer. Provide --issuer-cert ca.pfx --issuer-password CaPass.
Renewed cert still shows old expiry in browserBrowser or server has cached the old certificateRestart the web server and clear the browser certificate cache.
"Max validity exceeded"--days value is over 398Use --days 398 or lower. For longer durations, plan more frequent renewals.
Renewed cert has a different key than expectedNew key generated by defaultAdd --keep-key to preserve the original private key.
"Source certificate not found"Wrong file path or thumbprintVerify the path, or run certz store list --store My to confirm the thumbprint.