Sign Command

The sign command signs one or more files using a certificate held on the Signotaur server. The private key never leaves the server. It signs Windows executables and installers, NuGet and VSIX packages, PowerShell scripts, Apple configuration profiles, Remote Desktop files, ClickOnce and VSTO manifests, PDF and XML documents, and archives, choosing the right signature format for each file automatically.

Usage

SignotaurTool.exe sign [options] <files>

Files Parameter

  • A list of file paths to sign. You can specify individual file paths or use wildcards to match multiple files. This parameter supports the following wildcard patterns:

    • *: Matches zero or more characters within a file name. For example, *.exe will match all executable files in the specified directory.
    • ?: Matches a single character. For instance, file?.dll will match file1.dll, file2.dll, but not file12.dll.
    • **: Indicates a recursive search across all subdirectories. For example, **/*.exe will match all .exe files found in the current directory and all its subdirectories.
    • !: Identifies an exclude pattern. This must be at the start of the pattern. It must be used in conjunction with a normal include pattern. For instance, the two patterns *.dll and !*.Test.dll will match all .dll files found in the current directory excluded all test dlls, that is file1.dll, file2.dll, but not file1.Test.dll.
  • Examples:

    • *.exe: Matches all executable files in the specified directory.
    • C:\Projects\**\*.dll: Matches all dynamic link library files in the C:\Projects directory and any of its subdirectories.
    • C:\MyFiles\file?.exe: Matches any executable files that start with "file" followed by a single character.
    • !*.pdb: Matches all debug files in the specified directory from the current match.

    Wildcard patterns only search within the directory path you provide, so make sure the path points to the correct folder. To sign a large number of files, consider using --file-list to supply a text file listing the file paths instead.

ClickOnce and VSTO Content Pattern Filtering

When signing ClickOnce (.application) or VSTO (.vsto) files, you can specify which dependency files should be signed using content patterns. Use a colon (:) to separate the root file pattern from the content patterns. See ClickOnce and VSTO Signing.

Options at a Glance

Every option, in the order the reference below documents them. Two options are always required: a way to identify the certificate (Certificate Selection) and --file-digest.

Option What it does Group
-s, --sign-server Signotaur server URL Authentication
-a, --api-key API key for the server Authentication
--af, --api-key-file Read the API key from a file Authentication
--akn, --api-key-name Variable name holding the API key Authentication
--fe, --fail-if-expiring-within Fail if the API key expires soon Authentication
-t, --thumbprint Select the certificate by thumbprint Certificate Selection
-l, --label Select the certificate by label Certificate Selection
--sb, --subject Select the certificate by subject Certificate Selection
--ac, --additional-certs Add certificates to the signature block Certificate Selection
--fl, --file-list Read the file list from a file Input Files
-b, --base-directory Base directory for relative paths Input Files
--format Force a signature format for every file Format Selection
--dt, --detached Write a separate signature file Detached Signatures
--sf, --signature-file Where to write the detached signature Detached Signatures
--lv, --level AdES signature level Document Signing
--cl, --cades-level CAdES level (prefer --level) Document Signing
--ce, --cades-encoding CAdES encoding, DER or Base64 Document Signing
--cm, --cades-mode CAdES detached or enveloping Document Signing
--xp, --xades-placement XAdES enveloped, detached or enveloping Document Signing
--xl, --xades-level XAdES level (prefer --level) Document Signing
--pl, --pades-level PAdES level (prefer --level) Document Signing
--pv, --pades-visible Draw a visible signature appearance Document Signing
--pp, --pades-page Page to attach the signature to Document Signing
--pr, --pades-rect Appearance rectangle Document Signing
--prsn, --pades-reason Reason text in the appearance Document Signing
--ploc, --pades-location Location text in the appearance Document Signing
--pfont, --pades-font Font to embed in the appearance Document Signing
--pimg, --pades-image Image drawn in the appearance Document Signing
--ppwd, --pades-password Open password for an encrypted PDF Document Signing
--px, --pades-xref Cross-reference style Document Signing
--uf, --unsupported-file-types What to do with unrecognised files Unsupported File Types
-d, --description Description embedded in the signature Signature Metadata
--du, --description-url URL for an expanded description Signature Metadata
--an, --app-name Application name for ClickOnce and VSTO Signature Metadata
--fd, --file-digest Required. Digest algorithm Digest and Page Hashing
--ph, --page-hashing Generate page hashes Digest and Page Hashing
--nph, --no-page-hashing Suppress page hashes Digest and Page Hashing
--tr, --timestamp-server RFC 3161 timestamp server URL Timestamping
--td, --timestamp-digest Timestamp digest algorithm Timestamping
--fb, --fallback-timestamp-server Timestamp servers to try on failure Timestamping
--st, --separate-timestamp Timestamp in a second step Timestamping
--vc, --verify-cert-chain Verify the chain before signing Signature Validation
--rm, --revocation-mode How revocation is checked Signature Validation
--ir, --ignore-untrusted-root Allow an untrusted root Signature Validation
--sl, --strict-lifetime Enforce validity strictly when verifying Signature Validation
--as, --append-signature Add a signature without replacing Signing Behaviour
--sha1, --add-sha1-signature Dual-sign for legacy Windows Signing Behaviour
--vf, --verify Verify the signature after signing Signing Behaviour
--ss, --skip-signed Skip files already signed Signing Behaviour
--au, --allow-untrusted Accept an untrusted Signotaur server Signing Behaviour
--auc, --allow-untrusted-crl Accept an untrusted revocation endpoint Signing Behaviour
--cf, --continue-on-fail Keep going after a file fails Signing Behaviour
--asu, --auto-self-update Update the tool before signing Updating
--um, --update-mode When an update is considered new Updating
--wp, --warn-wrong-purpose Warn instead of failing on a wrong purpose Certificate Requirements
--nmg, --no-mstsc-guidance Suppress the post-sign RDP guidance Output and Diagnostics
--encoding Console output encoding Output and Diagnostics
--theme Console colour theme Output and Diagnostics
--nc, --no-colour Disable coloured output Output and Diagnostics
-v, --verbose Verbose logging Output and Diagnostics
--nb Hide the banner Output and Diagnostics
--rt, --request-timeout Server request timeout Miscellaneous
-m, --max-degree-of-parallelism Concurrent signing operations Miscellaneous
--help Show help for this command Miscellaneous

What Gets Signed, and How

Every input file is routed to a signature format before anything is signed. The table below is the whole mapping. For how each format is constructed, see Signature Formats by File Type.

Input Signed as Where the signature goes
.exe, .dll, .msi, .msix, .cab, .cat, .sys, .ocx, .vbs, .winmd and the other PE and installer formats Authenticode Inside the file
.ps1, .psm1, .psd1, .ps1xml, .cdxml Authenticode Inside the file
.mobileconfig, .mobileprovision, .provisionprofile CMS/PKCS#7 Wrapped around the content
.nupkg NuGet Inside the package
.vsix VSIX (OPC XML) Inside the package
.application, .manifest, .vsto ClickOnce and VSTO Inside the manifests
.rdp RDP Inside the file, as a signature:s: line
.pdf PAdES Inside the PDF
.xml XAdES Inside the XML by default
.zip, .7z, .tar, .gz, .tgz, .bz2, .xz, .iso, .img, .vhd, .vhdx Detached CMS A separate <file>.p7s
Anything else Decided by --unsupported-file-types Depends on the action chosen

The routing decision is made like this:

  1. If --format names a format other than Auto, that format is forced for every input file, and the rest of this list does not apply.
  2. Any file whose bytes are a valid Windows PE image is signed with Authenticode, whatever it is called. Detection is by content, not only by extension.
  3. Otherwise the extension decides, as in the table above.
  4. Archives and disk images are detached automatically. --detached extends detached output to other file types.
  5. Anything still unmatched is handled by --unsupported-file-types.

CAdES is the exception to the table: it has no extension of its own, so it is only produced by asking for it with --format CAdES, or by giving a --level with detached output.

Because step 2 tests the bytes rather than the name, staged binaries emitted by build tools sign correctly with no extra options. The .tmp files InstallShield hands to a signing step are the common case: they are PE images, so they take an Authenticode signature without needing --unsupported-file-types UseAuthenticodeSigning.

Options

Authentication

  • -s, --sign-server <URL>

    The URL of the Signotaur server that will handle the signing operation. Required unless provided via the SIGNOTAUR_SERVER environment variable or configuration file.

  • -a, --api-key <APIKey>

    Required (unless using --api-key-file, environment variable, or config file). Specifies the Signotaur API key needed to authenticate with the Signotaur service.

  • --af, --api-key-file <Path>

    Path to file containing API key (alternative to --api-key). The file can be a plain text file containing just the API key, or a dotenv file with SIGNOTAUR_API_KEY=<key> format. This is more secure than passing the key via command line as it doesn't appear in shell history.

  • --akn, --api-key-name <VarName>

    Specifies the variable name for reading the API key from an environment variable or dotenv file (default: SIGNOTAUR_API_KEY). Use this to specify a custom environment variable name or to read a specific variable from a dotenv file when using --api-key-file.

  • --fe, --fail-if-expiring-within <Duration>

    Fail if API key expires within specified duration. Prevents signing with keys that are about to expire. Duration format examples: 7d (7 days), 24h (24 hours), 30d (30 days), 1w (1 week), 2w (2 weeks).

API Key Resolution Priority:

  1. --api-key (command line argument)
  2. --api-key-file (file path)
  3. Environment variable (SIGNOTAUR_API_KEY or custom name via --api-key-name)

For detailed workflows on securing and managing API keys via CLI, see API Key Management.

Server URL Resolution:

The server URL can be provided via:

  1. --sign-server (command line argument)
  2. SIGNOTAUR_SERVER environment variable
  3. Configuration file (signServer key)

Certificate Selection

One of --thumbprint, --label, or --subject is required to identify the signing certificate. If multiple options are provided, they are evaluated in priority order: thumbprint → label → subject.

  • -t, --thumbprint <Thumbprint>

    Specifies the certificate thumbprint to be used for signing. You can obtain this thumbprint from the Signotaur certificate page. This provides the most specific certificate identification (exact match).

  • -l, --label <LABEL>

    Certificate label for simplified certificate selection. Labels are user-friendly identifiers (e.g., "production", "test") assigned to certificates in the Signotaur server admin interface. When multiple non-expired certificates share the same label, the certificate with the latest expiration date is automatically selected. This allows you to renew certificates without updating your build scripts - simply assign the same label to the new certificate. Case-insensitive matching is used.

  • --sb, --subject <Subject>

    Specifies the certificate subject. This is the least specific option. If multiple certificates with the same subject exist, the operation will fail with an error.

  • --ac, --additional-certs <CertList>

    Adds additional certificates from file paths to the signature block. You can provide a comma-separated list of certificate file paths. This is useful for including intermediate or root certificates that may be necessary for validation.

The certificate must also be marked for the kind of artefact being signed. See Certificate Requirements.

Input Files

  • --fl, --file-list <FileName>

    Specifies the path to a file containing a list of files to sign. This is useful for batch signing multiple files without specifying them individually on the command line.

    Each line in the file must follow this format:

    FilePath|Description|URL|ApplicationName
    
    • FilePath (required): The path to the file to be signed. This can be a specific file path or use wildcards (*, ?, **) to match multiple files. The tool will interpret each path just as it does for the Files parameter. For ClickOnce/VSTO files, you can use the content pattern syntax (:) to filter dependencies (e.g., MyApp.application:*.dll:*.exe).
    • Description (optional): A description of the signed content. Overrides the -d or --description option for the specified file or matching files.
    • URL (optional): A URL for an expanded description of the signed content. Overrides the -du or --description-ul option for the specified file or matching files.
    • ApplicationName (optional): Specifies an application name for use with ClickOnce or VSTO manifests. Overrides the --an or --app-name option for the specified file or matching files.

    Quoting and escaping rules

    • Quotes are optional unless a field contains a pipe (|) or a double quote (").
    • If a field contains a pipe (|) or a double quote ("), it must be enclosed in double quotes ("").
    • Double quotes inside a quoted field must be escaped using a backslash (\").
    • Backslashes (\) must be escaped (\\) inside a quoted field, but remain unchanged if unquoted.

    Example entries

    C:\Folder\*.exe
    C:\Users\user\*.dll|Sample description
    "C:\Projects\**\file.dll"|"A \"quoted\" description"|"http://example.com"
    "C:\Dev\drivers\*.sys"|"System drivers"|http://example.com
    "*.dll"|"This description contains a | pipe character"|http://example.com
    "E:\Publish\App\app.exe"|Description with spaces|https://example.com
    
  • -b, --base-directory <Directory>

    Sets the base directory for resolving relative file paths.

Format Selection

  • --format <Format>

    Selects the signature format for every input file. Values: Auto (default), Authenticode, Cms, NuGet, Vsix, Rdp, ClickOnce, XAdES, PAdES, CAdES.

    Auto detects by extension and content, as described in What Gets Signed, and How.

    Any other value forces that signer for every input file, overriding detection. --format cms CMS-signs even an .exe or .nupkg; --format authenticode, --format nuget, --format vsix and --format rdp force those signers in the same way. CAdES must be selected here, because it has no file extension of its own.

    ClickOnce is the exception: it is detection-only and does not force.

    Forcing a format changes what the certificate must be marked for, because the purpose check follows the signature each file actually receives. See Certificate Requirements.

Detached Signatures

Some artifacts have no standard for an embedded signature, most notably archives and disk images. Signing these in place (for example with --unsupported-file-types UseCMSSigning) would wrap the whole file in a PKCS#7 envelope and destroy the original. Instead, Signotaur writes a detached CMS/PKCS#7 signature to a separate .p7s file, leaving the original byte-for-byte unchanged.

Archive and disk-image formats are signed this way automatically, with no extra flags:

SignotaurTool sign archive.zip --fd SHA256 -a <api-key> -t <thumbprint>

This signs archive.zip and writes the signature to archive.zip.p7s alongside it; archive.zip itself is not modified.

  • --dt, --detached

    Extend detached signing to file types that have no embedded-signature format (for example .txt, .json, or arbitrary binaries). The archive and disk-image formats do not require this flag. Known formats (PE, MSI, NuGet, VSIX, RDP, ClickOnce, .mobileconfig) always use their native embedded signatures and ignore --detached.

  • --sf, --signature-file <Pattern>

    Override the detached signature output path. By default a <file>.p7s signature file is written next to each signed file.

    • Exact path (no placeholder): only valid when signing a single file. The path can be a bare filename (written to the current directory) or include a directory:

      SignotaurTool sign archive.zip --signature-file archive.sig ...
      SignotaurTool sign archive.zip --signature-file C:\sigs\archive.sig ...
      
    • Placeholder pattern (batch): substituted for each file, so it works across wildcards and --file-list:

      • {name}: the file's full name including its extension (for example archive.zip)
      • {name-no-ext}: the file's name without its final extension (for example archive)
      • {rel-path}: the file's path relative to the base directory, including the filename (for example src\a\archive.zip). This recreates the input folder structure under the output directory.

      The pattern can write signatures to the current directory or collect them under a directory:

      SignotaurTool sign *.zip --signature-file {name}.p7s ...
      SignotaurTool sign *.zip --signature-file sigs\{name}.p7s ...
      

      The first writes archive.zip.p7s, report.zip.p7s, and so on; the second writes sigs\archive.zip.p7s, sigs\report.zip.p7s. (Using {name-no-ext} instead of {name} would write archive.p7s / sigs\archive.p7s.)

      When signing a recursive tree, {name} would make files with the same name in different folders collide. Use {rel-path} to keep them distinct:

      SignotaurTool sign src\**\*.zip --signature-file sigs\{rel-path}.p7s ...
      

      signs src\a\archive.zip and src\b\archive.zip to sigs\src\a\archive.zip.p7s and sigs\src\b\archive.zip.p7s respectively. The base directory is the directory the command runs in, or --base-directory when set. So --base-directory src would instead write sigs\a\archive.zip.p7s. A file located outside the base directory falls back to just its filename (with a warning), so the output can never escape the pattern's root.

    Any directory in the output path is created automatically if it does not already exist, including nested directories.

    The .p7s signature file is a standard CMS/PKCS#7 SignedData structure. It can be verified with SignotaurTool verify or any standards-compliant tool, for example:

    openssl cms -verify -binary -inform DER -in archive.zip.p7s -content archive.zip -CAfile root.pem
    

Document Signing (AdES)

Signotaur signs PDF, XML and other documents using the AdES formats: PAdES, XAdES and CAdES. For a task-oriented guide see Signing Documents; this section is the option reference.

Producing a document signature needs a server with an Enterprise licence. Without one the document files in a batch are refused (code files still sign) and the run ends with exit code 87. See Signing Documents.

  • --lv, --level <Level>

    The AdES signature level, in plain language. Values: baseline (or B, the default), timestamped (T), long-term (LT), archival (LTA). Case-insensitive; hyphens and underscores are ignored.

    timestamped and above require --timestamp-server, or the command fails validation and nothing is signed. long-term and archival additionally collect revocation evidence (OCSP, falling back to CRL) from the signing certificate's AIA/CDP addresses; a certificate with none produces a warning and a signature with no embedded evidence. If those addresses are HTTPS and served with a certificate the signing machine does not trust, add --allow-untrusted-crl.

    This is the main level control. It applies to whichever AdES format each file uses, and overrides --cades-level, --xades-level and --pades-level. On a non-AdES file it is ignored, with a per-file warning.

CAdES Options

  • --cl, --cades-level <Level>

    Bes (default), T, Xl (long-term), or Lta (archival). T and above require --timestamp-server. Prefer --level.

  • --ce, --cades-encoding <Encoding>

    Der (default, binary) or Base64.

  • --cm, --cades-mode <Mode>

    Detached (default) keeps the content in the original file and writes a separate .p7s; Enveloping carries a copy of the content inside the signature and writes a single file with the .p7m extension.

XAdES Options

  • --xp, --xades-placement <Placement>

    Enveloped (default) adds the signature inside the .xml; Detached writes a separate <file>.sig and leaves the original untouched; Enveloping wraps a copy of the XML inside the signature. --detached selects the detached placement, so this option is rarely needed.

  • --xl, --xades-level <Level>

    B_B (default), B_T, B_LT or B_LTA. B_T and above require --timestamp-server. Prefer --level.

PAdES Options

  • --pl, --pades-level <Level>

    B_B (default), B_T, B_LT or B_LTA. All four are supported. B_T and above require --timestamp-server. Prefer --level.

  • --pv, --pades-visible

    Draw a visible signature appearance. The default is an invisible (but fully valid) signature.

    --pades-rect, --pades-reason, --pades-location, --pades-font and --pades-image are all drawn into that appearance. Without --pades-visible there is nothing to draw them in, so they are ignored with a warning. --pades-page is the exception: the signature is attached to that page whether it is drawn or not.

  • --pp, --pades-page <Page>

    The page to draw the appearance on, counting from 1. Default 1.

  • --pr, --pades-rect <Rect>

    The appearance rectangle as "x,y,width,height" in PDF points, measured from the bottom-left corner of the page. Default 36,36,220,64.

  • --prsn, --pades-reason <Reason> and --ploc, --pades-location <Location>

    Reason and location text drawn in the appearance box.

  • --pfont, --pades-font <FontPath>

    Path to a TrueType or OpenType font to embed. Required for text outside the Latin-1 character set.

  • --pimg, --pades-image <ImagePath>

    Path to a JPEG or PNG drawn in the appearance box.

  • --ppwd, --pades-password <Password>

    The user (open) password for signing a PDF protected by the standard security handler.

  • --px, --pades-xref <Style>

    Cross-reference style for the incremental update: Auto (default, matching the original PDF), Classic (table) or Stream.

PAdES has no detached form. Under --format Auto, a .pdf in a batch that requests detached output (via --detached or --signature-file) is written as a detached CAdES .p7s when a --level is given, or a plain CMS .p7s otherwise, with a warning that no PDF reader will show a signature. Combining --detached with an explicit --format pades is an error rather than a downgrade.

There is no --pades-contact option, and no option for CAdES parallel signatures: each run produces a single signer. AdES behaviour is command-line only; there are no client configuration-file keys for it.

Unsupported File Types

Everything in What Gets Signed, and How is signed automatically. This option governs what happens to input that matched none of it.

  • --uf, --unsupported-file-types <Action>

    • Fail (default): Error on unrecognised file types. The whole batch is checked before any file is signed, so an unrecognised file stops the run without producing output. Add --continue-on-fail to sign the rest of the batch around it.
    • Ignore: Skip unrecognised files with a warning.
    • UseCMSSigning: Sign unrecognised files using CMS/PKCS#7. The file content is wrapped in a PKCS#7 SignedData envelope.
    • UseAuthenticodeSigning: Sign unrecognised files using Authenticode. This will fail for file types not supported by a Windows Subject Interface Package (SIP).

    CMS/PKCS#7 signing wraps the entire file content in a cryptographic envelope. This is appropriate for formats that expect CMS wrapping (such as Apple .mobileconfig profiles) but should not be used for executable formats like .exe or .dll where Authenticode embeds the signature within the existing file structure. To sign a file of any type without altering it, use --detached instead.

    UseAuthenticodeSigning and UseCMSSigning both change what the certificate must be marked for. See Certificate Requirements.

Signature Metadata

  • -d, --description <Description>

    Specifies a description of the signed content. This description will be embedded in the signature and should provide context about the content being signed.

  • --du, --description-url <URL>

    Specifies a URL for an expanded description of the signed content. This URL can point to a webpage or document that provides more detailed information about the signed files.

  • --an, --app-name <Name>

    Specifies an application name - only used when signing ClickOnce/VSTO manifests.

Digest and Page Hashing

  • --fd, --file-digest <Algorithm>

    Required. Specifies the file digest algorithm to use for creating file signatures. Supported algorithms include: SHA256, SHA384, SHA512.

  • --ph, --page-hashing

    Enables the generation of page hashes for executable files if supported by the file type. This is useful for ensuring the integrity of the executable's pages and can help detect tampering.

  • --nph, --no-page-hashing

    Suppresses the generation of page hashes for executable files if supported. Use this option if you do not want to include page hashes in the signature.

Timestamping

  • --tr, --timestamp-server <TimeStampServer>

    Specifies the URL of the RFC 3161 timestamp server. Time stamping is important for proving when a file was signed. If this option is not included, the signed file will not be timestamped. A warning will be generated if timestamping fails.

  • --td, --timestamp-digest <DigestAlgorithm>

    Specifies the digest algorithm used by the RFC 3161 timestamp server. This option is required if the --tr option is provided. Supported algorithms include SHA256, SHA384, and SHA512.

  • --fb, --fallback-timestamp-server <FallbackTimeStampServers>

    Specifies one or more URLs for RFC 3161-compliant timestamp servers to use as fallbacks if the primary timestamp server (--tr) fails. Provide multiple servers by repeating this option. The servers are tried sequentially, stopping at the first successful response.

  • --st, --separate-timestamp

    Enables a separate time-stamping step after signing. Supported for Authenticode (.exe, .dll, .msi, .cat, etc.), CMS (.mobileconfig, .mobileprovision, .provisionprofile), detached CMS signature files (.p7s), NuGet (.nupkg), VSIX (.vsix), and RDP (.rdp) files. ClickOnce/VSTO manifests are always timestamped inline; post-sign timestamping is not supported for manifests because the timestamp is embedded inside the manifest's strong-name-signed scope.

    Automatically activated when any fallback timestamp servers (--fb) are specified.

    Failure behaviour differs between inline and separate modes:

    • Without --st (inline mode): signing and timestamping are atomic. If the TSA fails, the file on disk is unchanged.
    • With --st (separate mode): the file is signed first, then timestamped in a second step. If the TSA fails, the file is left on disk signed but not timestamped; the signing command exits with a timestamp error. You can add a timestamp later without re-signing by running the timestamp subcommand.

    The AdES formats embed their timestamp as they sign, so --separate-timestamp does not apply to a document batch.

Signature Validation

  • --vc, --verify-cert-chain

    Verifies the certificate chain before signing. If not set, the chain is not verified (default). Enables --revocation-mode and optionally --ignore-untrusted-root.

  • --rm, --revocation-mode <Mode>

    Specify the revocation check mode when building the certificate chain. Only used during signing when --verify-cert-chain is enabled.

    By default, the chain-building process may try to check the certificate status against online Certificate Revocation Lists (CRLs) or Online Certificate Status Protocol (OCSP) responders. If these URLs are inaccessible or slow to respond, possibly due to firewall restrictions, then changing the revocation mode can improve signing performance. The parameter accepts the following <Mode> values:

    • Online (default): Performs live revocation checks.
    • Offline: Skips online checks and uses cached data.
    • NoCheck: Disables all revocation validation, increasing the risk of using revoked certificates.

    Note: Software signed with a revoked certificate may trigger trust warnings or be blocked by operating systems. We therefore recommend checking and adjusting your firewall settings first. Ensure that it permits outbound HTTP (port 80) and HTTPS (port 443) traffic to the CRL and OCSP URLs specified in your certificates.

  • --ir, --ignore-untrusted-root

    Ignore untrusted root errors. When signing, it allows certificate chains that do not terminate in a trusted root (requires --verify-cert-chain). When verifying, this skips errors caused by unknown or self-signed root certificates.

  • --sl, --strict-lifetime

    Strictly enforce signature validity to the certificate's validity period when verifying and a timestamp is present.

Signing Behaviour

  • --as, --append-signature

    Appends this signature to the file. If no primary signature exists, this signature will become the primary one. This is useful for signing files multiple times without overwriting existing signatures.

  • --sha1, --add-sha1-signature

    Adds an additional SHA-1 signature for dual-signing to support legacy Windows versions. This allows files to be trusted on older operating systems that do not support modern SHA-256 or higher digest algorithms, while maintaining a primary signature with a stronger algorithm.

    Dual signing requires an RSA code-signing certificate. ECDSA certificates cannot be used with --sha1: the secondary signature fails to append with an E_INVALIDARG error, and ECDSA signatures are not validated by Windows versions older than Windows 8 in any case, so no legacy compatibility is gained. See Certificate recommendations for more detail.

    --append-signature and --add-sha1-signature have no effect alongside --skip-signed, since that skips the file entirely. Appending a signature is only officially supported on Windows Server 2022 and Windows 11 or later, and may not work reliably on Windows 10.

  • --vf, --verify

    Verifies the signature after signing to ensure it is valid.

  • --ss, --skip-signed

    Skips any files that have been previously signed.

  • --au, --allow-untrusted

    Allows signing using a Signotaur server that is bound to an untrusted or invalid certificate. Use this option with caution, as it may expose you to security risks.

  • --auc, --allow-untrusted-crl

    Allows the long-term signature levels to download revocation data (CRL and OCSP) from an HTTPS distribution point that is bound to an untrusted or invalid certificate.

    Whether you need it depends on the CA that issued your signing certificate, not on Signotaur. It applies when that CA publishes revocation data over HTTPS using a TLS certificate the signing machine does not trust, which any internal CA may do. Signotaur's own Internal CA serves its validation endpoints over plain http://, so certificates it issues do not normally need this.

    This is separate from --allow-untrusted, which covers only the connection to the Signotaur server: relaxing trust for one does not relax it for the other. It only affects --level long-term and --level archival (and the equivalent per-format levels), because those are the levels that fetch revocation data. Use it with the same caution.

    This option applies while signing. It cannot help anyone verifying the signature later, because that check runs through the operating system's own certificate handling, which has no equivalent option: an HTTPS distribution point must be trusted by the machine's certificate store, or verification reports CERT_E_REVOCATION_FAILURE. Install the issuing CA's root certificate on the verifying machine, or have the CA publish revocation data over plain http://, which is the usual practice precisely because it avoids this circularity.

  • --cf, --continue-on-fail

    Continues signing subsequent files even if an error occurs while signing a file. This option is useful for batch signing scenarios where you want to attempt to sign all files regardless of individual failures.

Updating

  • --asu, --auto-self-update

    Automatically checks for and installs updates before signing.
    If an update is installed, the updated version restarts with the same command-line arguments, excluding this option.

  • --um, --update-mode <Mode>

    Choose 'Version' to update to every new release, or 'SourceHash' (default) to update only when the source code hash differs (e.g. when there are changes).

Output and Diagnostics

  • --nmg, --no-mstsc-guidance

    Skip the post-sign Remote Desktop trust-configuration guidance printed after signing .rdp files. Useful in automation / CI where the guidance is just noise. See RDP file signing for details on the guidance output and the recipient-side configuration it explains.

  • --encoding <Encoding>

    Specifies the output encoding. Set to one of UTF8, UTF16, OEMCodePage or CodePage### where ### is the number of the code page to use. Defaults to UTF8.

  • --theme <Theme>

    Specifies the console colour theme. Options are: General (default, suitable for most consoles), Dark (optimized for dark backgrounds), Light (optimized for light backgrounds), or None (disables colours). The default is General.

  • --nc, --no-colour, --no-color

    Disables coloured output entirely. This is useful for CI/CD environments, log files, or systems that don't support ANSI colour codes. Alternatively, you can set the NO_COLOR environment variable to any non-empty value to achieve the same effect (following the no-color.org standard).

  • -v, --verbose

    Enables verbose logging for the signing operation, providing detailed output of the signing process, which can be useful for debugging.

  • --nb

    Hides the banner in the output, which may be useful for scripting or logging purposes where you want a clean output.

Miscellaneous

  • --rt, --request-timeout <TimeoutInSeconds>

    Specifies the request timeout for server requests in seconds. If the server takes longer than the specified time to respond, the operation will be aborted. Default is 0 for automatic timeout calculation based on number of files

  • -m, --max-degree-of-parallelism <MDOP>

    Specifies the maximum number of concurrent file signing operations. This setting allows you to control the degree of parallelism to optimize performance. The default value is 4, but you can adjust this based on the capabilities of your machine.

  • --help

    Displays help information and usage instructions for this command.

Certificate Requirements

The signing certificate has to permit what you are asking it to do. Signotaur checks that before it signs anything, and by default refuses the run rather than producing a signature nobody will accept.

When the check refuses, nothing is signed and the run ends with exit code 34. Two things are checked, in this order.

Key usage. The certificate's Key Usage extension must permit digitalSignature or nonRepudiation. A key that permits neither is not authorised to produce a signature at all, so it is refused for every file type, and no extended key usage overrides that. A certificate with no Key Usage extension is unrestricted and passes.

Extended key usage. Document formats (XAdES, CAdES, PAdES) require a document-signing EKU (Microsoft, Adobe or RFC 9336) or Email Protection. Code formats (Authenticode, CMS, NuGet, VSIX, RDP, ClickOnce) require the Code Signing EKU. A detached .p7s accepts either of those, because it signs file content of a kind it cannot determine, so any content-signing purpose covers it; only a certificate restricted to non-content purposes, such as TLS authentication or time stamping, is refused.

A certificate with no EKU extension at all, or with the Any Purpose usage, is treated as covering every purpose, so it is normally neither refused nor warned about. The one exception is a certificate with no EKU extension whose key usage is nonRepudiation without digitalSignature. That is the ETSI document-signing profile, whose key is not authorised to sign code, so it is refused for the code formats while still signing the document formats.

Whether it refuses or warns, the message lists the extended key usages the certificate actually carries, so the cause is visible without inspecting the certificate yourself.

What Decides the Required Purpose

The purpose required follows the signature each file actually receives, not the file's extension. --format and --unsupported-file-types UseAuthenticodeSigning therefore change what the certificate must carry: a file routed to Authenticode needs the Code Signing EKU whatever it is called, and --detached with a --level produces a CAdES document signature that needs a document-signing usage. Files skipped by --unsupported-file-types Ignore, or failed by its default, are never signed and so require nothing.

Overriding the Check

  • --wp, --warn-wrong-purpose

    Only warn, instead of failing, when the signing certificate is not marked for the kind of artefact being signed. The files are signed and the run continues.

Document signing additionally requires an Enterprise-licensed server, which is a separate check that --warn-wrong-purpose does not affect; see Signing Documents.

For what makes a certificate acceptable in the first place, see Code-Signing Certificates and Document-Signing Certificates.

Options That Do Not Apply Are Reported

Each per-format option reaches only its own signer, so one naming a format absent from the batch does nothing. Rather than dropping it in silence, sign warns once per run and continues:

  • A --cades-*, --xades-* or --pades-* option when no file in the batch is signed in that format.
  • An appearance option (--pades-rect, --pades-reason, --pades-location, --pades-font, --pades-image) without --pades-visible. --pades-page is not in this group: the signature is attached to that page whether it is drawn or not.
  • --pades-password on a PDF that turns out not to be encrypted.
  • --level alongside --cades-level, --xades-level or --pades-level, naming the per-format value it overrides.
  • --detached or --signature-file with --cades-mode Enveloping or --xades-placement Enveloping, where the placement wins and no separate signature file is written.
  • --timestamp-digest or --fallback-timestamp-server without --timestamp-server.
  • --separate-timestamp on a document batch: XAdES, PAdES and CAdES embed their timestamp as they sign.
  • --description and --description-url on a batch with no Authenticode file, as they are carried in an Authenticode-only attribute.

What counts is whether you supplied the option, not what you set it to: --cades-mode Detached on a batch with no CAdES file is reported even though Detached is the default, because typing it still achieved nothing. An option you did not supply is never reported.

Examples

  1. Sign multiple files with a specified thumbprint:

    SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 file1.exe file2.dll
    
  2. Sign files using certificate label (recommended for CI/CD):

    SignotaurTool.exe sign --api-key-file %USERPROFILE%\.signotaur\api_key.txt -s https://signotaur.example.com --label production --fd SHA256 *.exe
    
  3. Sign files with API key from file and expiration check:

    SignotaurTool.exe sign --api-key-file /path/to/key.txt --fail-if-expiring-within 7d -s <SignServer> --label production --fd SHA256 file1.exe
    
  4. Sign files with timestamping:

    SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 --tr <TimeStampServer> --td SHA256 file1.exe file2.dll
    
  5. Sign files with timestamping and verification:

    SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 --tr <TimeStampServer> --td SHA256 --vf file1.exe file2.dll
    
  6. Sign an Apple .mobileconfig profile (automatically uses CMS/PKCS#7):

    SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 profile.mobileconfig
    
  7. Sign a NuGet package (automatically detected):

    SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 --tr <TimeStampServer> --td SHA256 MyPackage.1.0.0.nupkg
    
  8. Sign a Visual Studio extension (automatically detected):

    SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 --tr <TimeStampServer> --td SHA256 MyExtension.vsix
    
  9. Sign a Microsoft Remote Desktop connection file (automatically detected):

    SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 connection.rdp
    
  10. Sign a PowerShell script (automatically uses Authenticode):

    SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 --tr <TimeStampServer> --td SHA256 Deploy.ps1
    
  11. Sign an unrecognised file type using CMS/PKCS#7:

    SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 --uf UseCMSSigning config.dat
    
  12. Sign an archive (automatically written as a detached .p7s):

    SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 release.zip
    
  13. Sign a PDF (automatically uses PAdES; requires an Enterprise licence):

    SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 --level timestamped --tr <TimeStampServer> --td SHA256 contract.pdf
    

Signature Formats by File Type

Which format each file receives is decided as described in What Gets Signed, and How. This section covers how each signature is constructed.

Authenticode

Authenticode signing covers the following file types: .appx, .appxbundle, .cab, .cat, .cdxml, .dll, .eappx, .eappxbundle, .emsix, .emsixbundle, .exe, .msi, .msix, .msixbundle, .msm, .msp, .mst, .ocx, .ps1, .ps1xml, .psd1, .psm1, .stl, .sys, .vbs, .vxd, .winmd. Additional PE file types are also signed automatically, since detection is by content.

PowerShell scripts and modules: .ps1 (scripts), .psm1 (modules), .psd1 (module manifests), .ps1xml (format and type definitions) and .cdxml (cmdlet definition XML) are signed with Authenticode, exactly the same way as an .exe. No PowerShell-specific options are required. For an end-to-end walkthrough covering execution policy, verification with Get-AuthenticodeSignature, and timestamping, see Signing PowerShell scripts.

CMS/PKCS#7

Apple configuration and provisioning profiles (.mobileconfig, .mobileprovision, .provisionprofile) are signed with CMS/PKCS#7, which wraps the file content in a SignedData envelope. Unrecognised file types can also be CMS-signed with --unsupported-file-types UseCMSSigning.

Detached CMS for Archives and Disk Images

.zip, .7z, .tar, .gz, .tgz, .bz2, .xz, .iso, .img, .vhd and .vhdx receive a detached CMS/PKCS#7 signature in a separate .p7s file, leaving the original untouched. --detached extends the same treatment to any other file type, and --signature-file controls where the sidecar is written.

NuGet Packages

NuGet packages (.nupkg) are signed using NuGet-specific signing. The signature is embedded as a .signature.p7s entry inside the package ZIP archive, conforming to the NuGet Package Signing specification. The signature includes:

  • Author signature with commitment-type-indication and signing-certificate-v2 attributes
  • RFC 3161 timestamp (when --tr is specified)
  • The same code-signing certificate used for other signing operations

Signed packages can be verified with dotnet nuget verify or with SignotaurTool.exe verify.

VSIX (Visual Studio Extensions)

VSIX packages (.vsix) are signed using OPC (Open Packaging Conventions) XML digital signatures, conforming to the format used by Visual Studio. Signing computes per-part digests with inclusive XML canonicalisation and writes the signature into the package as a signed XML manifest.

Signed packages can be verified with SignotaurTool.exe verify. RFC 3161 timestamping is supported when --tr is specified.

RDP Files

.rdp files (Microsoft Remote Desktop connection files) are signed using Microsoft's RDP file signing format: a detached CMS/PKCS#7 signature wrapped in Microsoft's 12-byte header and embedded into the file itself as a signature:s: line. The output is byte-structurally equivalent to what rdpsign.exe produces and is accepted by Windows Remote Desktop Connection.

After signing, the tool prints a guidance block explaining how recipients' Windows machines need to be configured to accept the signature without a warning dialog. Suppress it with --no-mstsc-guidance. See RDP file signing for the full recipient configuration and troubleshooting.

--tr and --td work for .rdp files and the timestamp is embedded into the CMS in the standard way, but mstsc.exe does not consult the timestamp when validating the signature. Once the signing certificate expires, signed .rdp files revert to the "Caution: Unknown remote connection" dialog regardless of the timestamp. This is a mstsc limitation, not a Signotaur one (Microsoft's own rdpsign.exe has no timestamping support at all). See Timestamping and certificate expiry for the full explanation and recommended approach.

ClickOnce and VSTO

If the input includes a .application file (ClickOnce deployment manifest) or a .vsto file (Visual Studio Tools for Office add-in manifest), the sign command automatically:

  • Detects and parses the manifest structure
  • Signs all dependency files and manifests in the correct order
  • Updates hash values throughout the manifest chain
  • For VSTO, signs both the nested and root .vsto files

See ClickOnce and VSTO Signing for detailed information about content filtering and application-specific options.

Document Formats (XAdES, PAdES, CAdES)

.xml files are signed as XAdES and .pdf files as PAdES. CAdES has no extension of its own and is selected with --format CAdES, or produced when a --level is given with detached output. All three are ETSI Advanced Electronic Signatures and support four levels, from a baseline signature to an archival one that stays verifiable after the signing certificate expires. The options are in Document Signing (AdES); for a task-oriented guide see Signing Documents.

Exit Codes

The following exit codes indicate the result of the operation performed by SignotaurTool.exe sign. The most common failures are 4 Failure (server, gRPC, or unsupported-file errors), 47 TimeStampError (when --timestamp-server is specified), and chain-validation codes (20 UntrustedRoot, 21 CertificateExpired, 41 CertificateChaining, etc.) when --verify-cert-chain or --verify is in use. Codes 16–58 reach the sign command via the Windows SignerSignEx3 API for Authenticode files (.exe, .dll, .msi, .cat, .sys, etc.) and via cryptographic exceptions in the managed signers for CMS, NuGet, VSIX, and RDP files. Any HRESULT the Windows API can return is mappable here. Codes 12 AdditionalCertNotFound, 41 CertificateChaining, 43 PlatformNotSupported, 59 ApiKeyExpiring, and 60 InvalidDuration are produced by the sign command directly before any signing pipeline runs. Codes 66–85 cover additional Win32 file-system errors, cryptographic-message errors, and AppX/MSIX packaging errors surfaced when signing .appx/.msix packages.

  • 0 (Success): All files were signed successfully (S_OK).
  • 1 (NotFound): An input file was not found, or the server reported a missing resource (gRPC NotFound, HTTP 404, ERROR_FILE_NOT_FOUND).
  • 2 (Aborted): The operation was cancelled or its deadline expired (gRPC Cancelled / DeadlineExceeded, E_ABORT).
  • 3 (AccessDenied): Access denied. Either a local file permission error, or the server rejected the request as unauthenticated or unauthorised (gRPC Unauthenticated / PermissionDenied, HTTP 401, E_ACCESSDENIED).
  • 4 (Failure): General failure. An unexpected internal error or an unclassified server error (E_FAIL). Recognised gRPC error categories surface as more specific codes (1, 2, 3, 6, 64).
  • 5 (InvalidHandle): Invalid file handle (E_HANDLE).
  • 6 (InvalidArgument): One or more arguments are invalid or required arguments are missing, or the server rejected the request as invalid (gRPC InvalidArgument, E_INVALIDARG).
  • 7 (NoInterface): No such interface supported (E_NOINTERFACE).
  • 8 (NotImplemented): The requested feature is not implemented (E_NOTIMPL).
  • 9 (OutOfMemory): Out of memory (E_OUTOFMEMORY).
  • 10 (InvalidPointer): Invalid pointer (E_POINTER).
  • 11 (UnexpectedFailure): Unexpected catastrophic failure. For example, the server returned an unrecognised certificate response (E_UNEXPECTED).
  • 12 (AdditionalCertNotFound): A file passed to --additional-certs could not be found (CRYPT_E_NOT_FOUND).
  • 13 (FileListError): An error occurred while processing the --file-list file.
  • 14 (SharingViolation): An input file is locked by another process (ERROR_SHARING_VIOLATION).
  • 15 (UnknownResult): The cryptographic API returned an HRESULT that the client does not recognise.
  • 16 (NoSignature): --verify was specified but no signature was produced or could be located (TRUST_E_NOSIGNATURE).
  • 17 (ExplicitDistrust): The signing certificate is explicitly distrusted (TRUST_E_EXPLICIT_DISTRUST).
  • 18 (SubjectNotTrusted): The signing subject is not trusted (TRUST_E_SUBJECT_NOT_TRUSTED).
  • 19 (InvalidPolicy): The certificate policy is invalid or not allowed (CERT_E_INVALID_POLICY).
  • 20 (UntrustedRoot): The certificate chain terminates in an untrusted root (CERT_E_UNTRUSTEDROOT). Suppress with --ignore-untrusted-root.
  • 21 (CertificateExpired): The signing certificate has expired (CERT_E_EXPIRED).
  • 22 (Malformed): A certificate is malformed (CERT_E_MALFORMED).
  • 23 (CertificateRevoked): The signing certificate has been revoked (CERT_E_REVOKED).
  • 24 (FileError): A file error occurred while reading or writing the input file (CRYPT_E_FILE_ERROR).
  • 25 (ProviderUnknown): Unknown trust provider (TRUST_E_PROVIDER_UNKNOWN).
  • 26 (SubjectFormUnknown): Unknown trust subject form (TRUST_E_SUBJECT_FORM_UNKNOWN).
  • 27 (ActionUnknown): Unknown trust action (TRUST_E_ACTION_UNKNOWN).
  • 28 (TrustFailure): Generic trust verification failed (TRUST_E_FAIL).
  • 29 (CertificateIssuerChaining): A parent certificate is not correctly issued by a higher authority (CERT_E_ISSUERCHAINING).
  • 30 (CertificateValidityPeriodNesting): Validity periods in the chain do not nest correctly (CERT_E_VALIDITYPERIODNESTING).
  • 31 (CertificateRole): A certificate is being used in an invalid role (CERT_E_ROLE).
  • 32 (CertificatePathLenConst): A path-length constraint in the chain has been exceeded (CERT_E_PATHLENCONST).
  • 33 (CertificateCritical): A certificate has an unrecognised critical extension (CERT_E_CRITICAL).
  • 34 (CertificatePurpose): The certificate is being used for an invalid purpose (CERT_E_PURPOSE). Nothing is signed. See Certificate Requirements.
  • 35 (CertificateUntrustedTestRoot): The chain terminates in an untrusted test root (CERT_E_UNTRUSTEDTESTROOT).
  • 36 (CertificateRevocationFailure): The revocation check could not continue (CERT_E_REVOCATION_FAILURE). The chain itself was built; only its revocation status could not be established, for example because the CRL distribution point or OCSP responder could not be reached.
  • 37 (CertificateCNNoMatch): The certificate's common name does not match (CERT_E_CN_NO_MATCH).
  • 38 (CertificateWrongUsage): The certificate is not valid for the requested usage (CERT_E_WRONG_USAGE).
  • 39 (CertificateUntrustedCA): The issuing certificate authority is not trusted (CERT_E_UNTRUSTEDCA).
  • 40 (CertificateInvalidName): The certificate name is invalid (CERT_E_INVALID_NAME).
  • 41 (CertificateChaining): A certificate chain could not be built to a trusted root authority (CERT_E_CHAINING), including when an issuing certificate is not installed on the machine. Install the issuing CA certificates and try again. Earlier versions reported this case as 36 CertificateRevocationFailure.
  • 42 (SecuritySettings): The cryptographic operation was blocked by security policy or settings (CRYPT_E_SECURITY_SETTINGS).
  • 43 (PlatformNotSupported): An option is not supported on the current platform. For example, --append-signature on Windows versions older than Windows 11 / Windows Server 2022.
  • 44 (TrustSystemError): A system-level trust error occurred (TRUST_E_SYSTEM_ERROR).
  • 45 (TrustNoSignerCert): No signer certificate was found (TRUST_E_NO_SIGNER_CERT).
  • 46 (CannotInstallProvider): The certificate's signature could not be verified (TRUST_E_PROVIDER_UNKNOWN_ACTION).
  • 47 (TimeStampError): The timestamp server returned an error, was unreachable, or its certificate is invalid (TRUST_E_TIME_STAMP).
  • 48 (BadDigest): A signature or timestamp digest did not verify (TRUST_E_BAD_DIGEST). Reachable via --verify.
  • 49 (InvalidBasicConstraints): A certificate's basic-constraints extension is invalid or missing (TRUST_E_BASIC_CONSTRAINTS).
  • 50 (CounterSignerError): The countersignature or timestamp signature could not be verified (TRUST_E_COUNTER_SIGNER).
  • 51 (NoRevocationCheck): The revocation function was unable to check revocation (CRYPT_E_NO_REVOCATION_CHECK). Reachable when --verify-cert-chain and --revocation-mode Online are in use.
  • 52 (RevocationOffline): The revocation server was offline (CRYPT_E_REVOCATION_OFFLINE).
  • 54 (BadFormat): The input file is not in the expected format for its detected type (ERROR_BAD_FORMAT).
  • 55 (BadAsn1Tag): The timestamp server response contained an invalid ASN.1 tag, often caused by a misconfigured timestamp server URL or a proxy returning HTML (CRYPT_E_ASN1_BADTAG).
  • 56 (BadEncode): The timestamp server response could not be decoded (CRYPT_E_BAD_ENCODE).
  • 57 (BadMessage): The timestamp server response is not a valid cryptographic message (CRYPT_E_BAD_MSG).
  • 58 (BadAsn1Corrupt): The timestamp server response contained corrupt ASN.1 data (CRYPT_E_ASN1_CORRUPT).
  • 59 (ApiKeyExpiring): The API key expires within the threshold specified by --fail-if-expiring-within.
  • 60 (InvalidDuration): The --fail-if-expiring-within value is not a valid duration (use forms such as 7d, 24h, 1w).
  • 62 (MutuallyExclusiveOptions): Options that contradict each other were supplied together, such as --api-key with --api-key-file, or --detached with --format pades. Nothing is signed.
  • 64 (ServerUnavailable): The Signotaur server is unreachable or temporarily unable to service the request (gRPC Unavailable). Distinct from 4 Failure so CI/CD pipelines can retry-on-transient.
  • 66 (BadExeFormat): The file is not a valid Windows executable; despite its extension it contains no recognisable PE image (ERROR_BAD_EXE_FORMAT).
  • 67 (PathNotFound): A directory in the file path does not exist (ERROR_PATH_NOT_FOUND).
  • 68 (DiskFull): There is not enough free disk space to complete the operation (ERROR_DISK_FULL).
  • 69 (HashValueMismatch): The computed digest does not match the digest embedded in the signature; the file was modified after it was signed (CRYPT_E_HASH_VALUE). Reachable via --verify.
  • 70 (HandleEof): An end-of-file condition was reached unexpectedly; the input file is shorter than its structure declares, likely truncated or corrupt (ERROR_HANDLE_EOF).
  • 71 (NotEnoughMemory): The Win32 subsystem could not allocate the memory required to complete the operation (ERROR_NOT_ENOUGH_MEMORY).
  • 72 (LockViolation): The file is locked by another process and cannot be opened for writing; antivirus, an IDE, or a parallel build step may be holding the lock (ERROR_LOCK_VIOLATION).
  • 73 (AlreadyExists): The output file already exists (ERROR_ALREADY_EXISTS).
  • 74 (NotSupported): The requested operation is not supported for this input; the file type or option combination cannot be processed by the underlying API (ERROR_NOT_SUPPORTED).
  • 75 (SignerNotFound): No matching signer certificate was found in the signed message (CRYPT_E_SIGNER_NOT_FOUND).
  • 76 (AttributesMissing): Required signed or unsigned attributes are missing from the cryptographic message (CRYPT_E_ATTRIBUTES_MISSING).
  • 77 (AppxInvalidBlockMap): The AppxBlockMap.xml inside the package is missing or invalid (APPX_E_INVALID_BLOCKMAP).
  • 78 (AppxCorruptContent): A file inside the AppX/MSIX package was modified after the block map was generated (APPX_E_CORRUPT_CONTENT).
  • 79 (AppxInvalidManifest): The AppxManifest.xml inside the package is malformed or does not conform to the schema (APPX_E_INVALID_MANIFEST).
  • 80 (AppxMissingRequiredFile): The AppX/MSIX package is missing a required file such as AppxManifest.xml, AppxBlockMap.xml, or [Content_Types].xml (APPX_E_MISSING_REQUIRED_FILE).
  • 81 (AppxInvalidSipClientData): The AppX SIP rejected the client data passed during signing; typically a Signotaur-internal issue rather than a problem with the package (APPX_E_INVALID_SIP_CLIENT_DATA).
  • 82 (AppxBlockHashInvalid): A block hash recorded in AppxBlockMap.xml does not match the actual content of the file (APPX_E_BLOCK_HASH_INVALID).
  • 83 (CmsMessageError): A general error occurred while processing the cryptographic (CMS/PKCS#7) message (CRYPT_E_MSG_ERROR).
  • 84 (NoTrustedSigner): No trusted signer was found for the cryptographic message; commonly seen when a timestamp response is signed by a TSA whose certificate is not trusted (CRYPT_E_NO_TRUSTED_SIGNER).
  • 85 (NoKeyProperty): The certificate has no associated key property and cannot be used to sign (CRYPT_E_NO_KEY_PROPERTY).
  • 86 (RateLimited): The server's gRPC rate limit rejected the request. Back off and retry later. The limit is per API key and is off by default; an administrator sets it under Limits.GrpcRateLimit.
  • 87 (DocumentSigningNotLicensed): Document signing (XAdES, CAdES or PAdES) was refused because the server does not permit it. Document signing requires an Enterprise licence. A server too old to report the entitlement is refused as well, so upgrade the server if its licence already covers it. Only the document files are refused; code files in the same run still sign. See Signing Documents.

Typically a more specific message will be displayed before an error exit code is returned.

  • 34 (CertificatePurpose): the certificate is not marked for what is being signed. See Certificate Requirements.
  • 47 (TimeStampError): the timestamp authority was unreachable or returned a malformed token, which stops any level above baseline.
  • 54 (BadFormat): the input is not the format the chosen signer expects, for example a non-PDF file forced to --format pades.
  • 87 (DocumentSigningNotLicensed): as above.

Troubleshooting

  1. Server Connection Issues:

    • Ensure the Signotaur server URL is reachable.
    • Verify the server certificate is trusted unless using --allow-untrusted.
  2. Certificate Not Found:

    • Double-check the thumbprint or subject name.
    • Verify the certificate exists in the server's store.
  3. File Signing Errors:

    • Ensure the file path is correct.
    • Check permissions for accessing files and server resources.

Further Information

  • Signing Documents: a task-oriented guide to the AdES formats and levels.
  • Verify command: verifying the signatures produced here.