# Fix HashiCorp Vault PKI Certificate Read Error

You're trying to read PKI certificates from Vault with vault read pki/cert/ca but getting errors like "path not found", "permission denied", or the certificate isn't being returned correctly.

Vault's PKI secrets engine manages X.509 certificates for TLS. Let's troubleshoot common issues.

Introduction

This article covers troubleshooting steps and solutions for Fix HashiCorp Vault PKI Certificate Read Error. The error typically occurs in production environments and can cause service disruptions if not addressed promptly.

Symptoms

Common error messages include:

bash
vault secrets list | grep pki
bash
vault read pki/config/ca
vault read pki/config/urls
bash
vault list pki/certs

Common Causes

  • Configuration misconfiguration
  • Missing or incorrect credentials
  • Network connectivity issues
  • Version compatibility problems
  • Resource exhaustion or limits
  • Permission or access denied

Understanding Vault PKI Paths

Vault PKI uses specific paths for different operations:

PathDescription
pki/cert/caCA certificate (DER format)
pki/cert/ca_chainFull certificate chain
pki/cert/<serial>Specific certificate by serial
pki/issue/<role>Issue new certificate
pki/sign/<role>Sign CSR
pki/root/generate/internalGenerate root CA
pki/intermediate/generate/internalGenerate intermediate CA

Step-by-Step Fix

Check if PKI is enabled:

bash
vault secrets list | grep pki

Check PKI configuration:

bash
vault read pki/config/ca
vault read pki/config/urls

List certificates:

bash
vault list pki/certs

Check roles:

bash
vault list pki/roles
vault read pki/roles/<role-name>

Common Errors and Solutions

Error 1: Path Not Found

bash
vault read pki/cert/ca
# Error: no handler for route 'pki/cert/ca'

Cause: PKI secrets engine not enabled.

Solution: Enable PKI:

```bash # Enable PKI secrets engine vault secrets enable pki

# Set max TTL (default is 8760h = 1 year) vault secrets tune -max-lease-ttl=87600h pki

# Generate root CA vault write pki/root/generate/internal \ common_name="my-company.com" \ ttl=87600h

# Configure URLs vault write pki/config/urls \ issuing_certificates="http://vault:8200/v1/pki/ca" \ crl_distribution_points="http://vault:8200/v1/pki/crl" ```

Error 2: Permission Denied

bash
vault read pki/cert/ca
# Error: permission denied

Cause: Token or policy doesn't have read permission.

Solution: Create policy with PKI access:

```bash # Create policy vault policy write pki-reader - <<EOF path "pki/cert/ca" { capabilities = ["read"] } path "pki/cert/ca_chain" { capabilities = ["read"] } path "pki/cert/*" { capabilities = ["read"] } path "pki/roles/*" { capabilities = ["read", "list"] } path "pki/issue/*" { capabilities = ["update"] } EOF

# Create token with policy vault token create -policy=pki-reader ```

Error 3: Wrong Path Format

bash
vault read pki/ca
# Error: no handler for route

Cause: Using wrong path. The CA certificate is at pki/cert/ca, not pki/ca.

Solution: Use correct paths:

```bash # Read CA certificate (DER format) vault read pki/cert/ca

# Read CA chain (PEM format) vault read pki/cert/ca_chain

# For raw PEM CA certificate curl -s http://vault:8200/v1/pki/ca/pem ```

Error 4: Certificate Not Found by Serial

bash
vault read pki/cert/123456
# Error: certificate not found

Cause: Serial number format is wrong or certificate doesn't exist.

Solution: Use correct serial format:

```bash # List all certificates vault list pki/certs

# Serial format: hyphen-separated hex vault read pki/cert/12-34-56-78-90-ab-cd-ef

# Or use certificate ID from issue response # The response includes: certificate_id vault read pki/cert/<certificate_id> ```

Error 5: PKI Not Configured

bash
vault read pki/cert/ca
# Returns empty or no certificate

Cause: Root/intermediate CA not generated.

Solution: Generate CA:

```bash # Generate root CA vault write -format=json pki/root/generate/internal \ common_name="My Company Root CA" \ ttl=87600h > root_ca.json

# Extract certificate cat root_ca.json | jq -r '.data.certificate' > root_ca.crt

# For intermediate CA vault secrets enable -path=pki_int pki vault secrets tune -max-lease-ttl=43800h pki_int

# Set signed intermediate vault write pki_int/intermediate/set-signed \ certificate=@intermediate.cert.pem ```

Error 6: Role Not Found

bash
vault write pki/issue/my-role common_name="app.example.com"
# Error: role 'my-role' does not exist

Solution: Create role:

bash
vault write pki/roles/my-role \
  allowed_domains="example.com" \
  allow_subdomains=true \
  max_ttl=720h

Error 7: Invalid Certificate Format

bash
vault read pki/cert/ca
# Returns DER format, need PEM

Solution: Convert or use correct endpoint:

```bash # Get PEM format via API curl -s http://vault:8200/v1/pki/ca/pem

# Or convert DER to PEM vault read -format=json pki/cert/ca | jq -r '.data.certificate' | base64 -d > ca.der openssl x509 -inform DER -in ca.der -out ca.pem

# Get chain in PEM vault read -format=json pki/cert/ca_chain | jq -r '.data.certificate' > chain.pem ```

Error 8: CRL Not Accessible

bash
vault read pki/crl
# Error or empty CRL

Solution: Configure CRL:

```bash # Enable CRL building vault write pki/config/auto-crl \ enabled=true \ expiry="72h"

# Read CRL vault read pki/crl

# Get CRL via API curl -s http://vault:8200/v1/pki/crl/pem > crl.pem ```

Complete PKI Setup Example

Root CA Setup

```bash # Enable PKI vault secrets enable pki vault secrets tune -max-lease-ttl=87600h pki

# Generate root CA vault write pki/root/generate/internal \ common_name="My Company Root CA" \ country="US" \ locality="San Francisco" \ organization="My Company" \ ttl=87600h

# Configure URLs vault write pki/config/urls \ issuing_certificates="http://vault:8200/v1/pki/ca" \ crl_distribution_points="http://vault:8200/v1/pki/crl"

# Create role for issuing certificates vault write pki/roles/server-certs \ allowed_domains="example.com,app.example.com" \ allow_subdomains=true \ allow_bare_domains=true \ key_bits=2048 \ key_type="rsa" \ max_ttl=720h ```

Intermediate CA Setup

```bash # Enable intermediate PKI vault secrets enable -path=pki_int pki vault secrets tune -max-lease-ttl=43800h pki_int

# Import root CA vault write pki_int/intermediate/set-signed \ certificate=@intermediate.crt

# Configure URLs for intermediate vault write pki_int/config/urls \ issuing_certificates="http://vault:8200/v1/pki_int/ca" \ crl_distribution_points="http://vault:8200/v1/pki_int/crl"

# Create role vault write pki_int/roles/app-certs \ allowed_domains="app.example.com" \ allow_subdomains=true \ max_ttl=72h ```

Issue Certificate

```bash # Issue certificate vault write -format=json pki_int/issue/app-certs \ common_name="web.app.example.com" \ ttl=24h > cert.json

# Extract components cat cert.json | jq -r '.data.certificate' > cert.pem cat cert.json | jq -r '.data.private_key' > key.pem cat cert.json | jq -r '.data.ca_chain[]' >> cert.pem

# Verify certificate openssl x509 -in cert.pem -text -noout ```

Verification

```bash # Verify PKI is enabled vault secrets list | grep pki

# Check CA certificate vault read pki/cert/ca

# Verify CA chain vault read pki/cert/ca_chain

# Test certificate issuance vault write pki/issue/server-certs common_name="test.example.com" ttl=1h

# Verify issued certificate vault read pki/cert/<serial>

# Check roles vault list pki/roles vault read pki/roles/server-certs ```

Kubernetes Integration

yaml
# cert-manager with Vault PKI
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: vault-issuer
spec:
  vault:
    server: http://vault:8200
    path: pki_int/sign/app-certs
    auth:
      kubernetes:
        role: cert-manager
        mountPath: /v1/auth/kubernetes
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: app-cert
spec:
  secretName: app-tls
  issuerRef:
    name: vault-issuer
    kind: ClusterIssuer
  dnsNames:
    - app.example.com

Policy Examples

```bash # Admin policy vault policy write pki-admin - <<EOF path "pki/*" { capabilities = ["create", "read", "update", "delete", "list"] } path "pki_int/*" { capabilities = ["create", "read", "update", "delete", "list"] } EOF

# Issue-only policy vault policy write pki-issue - <<EOF path "pki/roles/*" { capabilities = ["read", "list"] } path "pki/issue/*" { capabilities = ["update"] } path "pki/cert/*" { capabilities = ["read"] } EOF

# Read-only policy vault policy write pki-read - <<EOF path "pki/cert/ca" { capabilities = ["read"] } path "pki/cert/ca_chain" { capabilities = ["read"] } path "pki/certs" { capabilities = ["list"] } EOF ```

  • [Fix Fix Admin Panel Blocked After Malware Cleanup Issue in Security Recovery](fix-admin-panel-blocked-after-malware-cleanup)
  • [Fix Fix Admin Password Reset Email Sent To Attacker Issue in Security Recovery](fix-admin-password-reset-email-sent-to-attacker)
  • [Fix Fix Adminer Or Phpmyadmin Exposed Publicly Issue in Security Recovery](fix-adminer-or-phpmyadmin-exposed-publicly)
  • [Fix Fix Apache Mod Security False Positive Admin Issue in Security Recovery](fix-apache-mod-security-false-positive-admin)
  • [Fix Apache mod_security False Positive Blocking Admin (security recovery variant 2)](fix-apache-mod-security-false-positive-blocking-admin)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix HashiCorp Vault PKI Certificate Read Error", "description": "Step-by-step guide to fix Vault PKI certificate read errors. Configure PKI secrets engine, resolve certificate access issues, and manage Vault PKI correctly.", "url": "https://www.fixwikihub.com/fix-vault-pki-cert-ca-read", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-27T10:10:00.000Z", "dateModified": "2026-04-27T10:10:00.000Z" } </script>