# IPsec VPN Troubleshooting in pfSense - Diagnostics Guide

> Diagnosing and resolving IPsec VPN issues in pfSense - log analysis, common Phase 1 and Phase 2 errors, parameter mismatches, and NAT-T problems

Source: https://opennix.org/en/docs/pfsense/vpn/ipsec/pfsense-ipsec-troubleshooting/


IPsec is a protocol with strict requirements for parameter matching on both sides of a tunnel. A mismatch in even a single parameter (encryption algorithm, DH group, subnet mask) causes the connection to fail, and error messages do not always point to the root cause. A systematic approach to diagnostics reduces troubleshooting time from hours to minutes.

This guide describes the methodology for diagnosing IPsec VPN issues in pfSense: from enabling debug logs through analyzing specific error messages. The material applies to both site-to-site and mobile client configurations.

## Enabling Debug Logs

By default, pfSense logs only basic IPsec events. For detailed diagnostics, the logging level must be increased.

### Configuring the Logging Level

Navigate to **VPN > IPsec > Advanced Settings** and configure the logging parameters:

| Parameter | Recommended Level | Purpose |
|---|---|---|
| IKE SA | Diag | Detailed Phase 1 negotiation information |
| IKE Child SA | Diag | Detailed Phase 2 negotiation information |
| Configuration Backend | Diag | Configuration loading and parameters |
| IKE Network Events | Control | Network events (connections, disconnections) |
| IKE Message Encoding | Control | IKE message encoding and decoding |
| IKE Manager | Control | IKE SA management |
| All others | Control | Standard level |

Click **Save**. Changing the logging level does not disrupt existing IPsec tunnels.

> **Warning**:
>
> The Diag level generates a significant volume of logs. After completing diagnostics, it is recommended to revert levels to Control to avoid filling disk space.

### Viewing Logs

IPsec logs are available under **Status > System Logs > IPsec**. Use the search field at the top of the page to filter entries.

To view logs in real time via the command line:

```bash
# Real-time IPsec log monitoring
clog -f /var/log/ipsec.log

# Filter for specific peer IP
clog -f /var/log/ipsec.log | grep "203.0.113.10"

# Filter for errors only
clog -f /var/log/ipsec.log | grep -i "error\|failed\|no proposal"
```

### Key Log Indicators

The following entries indicate successful or failed negotiation:

| Log Entry | Meaning |
|---|---|
| `IKE_SA ... established` | Phase 1 successfully established |
| `CHILD_SA ... established` | Phase 2 successfully established, tunnel active |
| `received NO_PROPOSAL_CHOSEN` | Remote side rejected the proposed parameters |
| `received AUTHENTICATION_FAILED` | Authentication error (PSK or certificate) |
| `no matching CHILD_SA config found` | Subnet mismatch (Traffic Selectors) |
| `giving up after N retransmits` | Remote side not responding |
| `peer didn't accept any proposal` | None of the proposed parameter sets were acceptable |

## Common Phase 1 Errors

Phase 1 (IKE SA) handles mutual authentication and security parameter negotiation. Errors at this stage completely prevent tunnel establishment.

### Encryption Parameter Mismatch

| Error Message | Cause | Solution |
|---|---|---|
| `received NO_PROPOSAL_CHOSEN` | Encryption algorithm, hash, or DH Group mismatch | Compare Encryption Algorithm parameters on both sides; all three components (cipher, hash, DH Group) must match |
| `no acceptable ENCRYPTION_ALGORITHM found` | Remote side does not support the proposed algorithm | Add an algorithm supported by the remote side, or agree on a common set |
| `no acceptable INTEGRITY_ALGORITHM found` | Hash algorithm mismatch | Set the same Hash Algorithm (SHA256, SHA384, SHA512) on both sides |
| `no acceptable DIFFIE_HELLMAN_GROUP found` | DH Group mismatch | Set the same DH Group; Group 14 (2048 bit) or higher is recommended |

When using AES-GCM in Phase 1, note that some implementations (Cisco ASA, older MikroTik versions) do not support GCM for IKE. In such cases, use AES-CBC with a separate hash algorithm.

### Authentication Errors

| Error Message | Cause | Solution |
|---|---|---|
| `received AUTHENTICATION_FAILED` | PSK mismatch or certificate verification failure | For PSK: verify exact key match (case, spaces, special characters). For certificates: ensure the CA certificate is imported on both sides |
| `PEER_AUTH_FAILED` | Remote side failed identity verification | Verify the remote side identifier (IP, FQDN, DN) |
| `invalid HASH_V1 payload length, decryption failed?` | PSK mismatch (IKEv1) | Recreate the PSK on both sides |
| `could not decrypt payloads` | PSK mismatch | Check the PSK on both sides, paying attention to invisible characters (trailing spaces, newlines) |

> **Warning**:
>
> When copying a PSK via the clipboard, invisible characters (spaces, newline characters) are often appended. It is recommended to type the key manually or use a random string generator.

### Identifier Errors

| Error Message | Cause | Solution |
|---|---|---|
| `no IKE config found for ... - ...` | Remote side identifier does not match settings | Check My identifier and Peer identifier values on both sides |
| `remote host is behind NAT, sending keep alives` + failure | Peer identifier set to IP address, but NAT changed the address | Change Peer identifier to `Distinguished Name` or `User FQDN` type instead of `Peer IP Address` |
| `parsed CERT_REQ payload, but no certificate found` | Certificate requested but not configured | Verify that the server certificate is specified in Phase 1 and has not expired |

### Unreachable Remote Peer

| Error Message | Cause | Solution |
|---|---|---|
| `giving up after 5 retransmits` | Remote peer not responding | Check: 1) Remote peer IP address; 2) UDP 500 and 4500 are not blocked; 3) IPsec service is running on the remote peer |
| `connection timed out` | No network connectivity | Verify routing to the remote peer (ping, traceroute) |
| `sending retransmit N of request message` | Packets are being sent but no response received | The issue may be on intermediate equipment (ISP firewall, NAT device) |

### DPD Errors

| Error Message | Cause | Solution |
|---|---|---|
| `DPD: peer is considered dead` | Remote peer did not respond to DPD requests | Check network connectivity; increase DPD Delay (30 seconds) and Max Failures (10) |
| `deleting IKE_SA ... after DPD timeout` | Tunnel removed due to DPD timeout | If the link is unstable, increase DPD timers or use keep-alive ping |
| Frequent disconnections and reconnections | UDP packet loss on intermediate equipment | Check link quality; if using QoS, ensure UDP 500/4500 is not rate-limited |

## Common Phase 2 Errors

Phase 2 (Child SA / IPsec SA) is negotiated within the secure Phase 1 channel. Phase 2 errors occur when Phase 1 is established - the Phase 1 status shows `Established`, but no Child SA is created.

### Subnet Mismatch (Traffic Selectors)

| Error Message | Cause | Solution |
|---|---|---|
| `no matching CHILD_SA config found` | Phase 2 subnets do not match those proposed by the remote side | Ensure that Local Network on one side corresponds to Remote Network on the other (mirror match) |
| `TS_UNACCEPTABLE` | Traffic Selectors rejected | Check the subnet mask: `/24` and `/32` are different values. A common mistake is specifying a host (`10.1.0.0/32`) instead of a network (`10.1.0.0/24`) |
| `received TS_UNACCEPTABLE notify, no CHILD_SA built` | Remote side did not accept the proposed subnets | Compare Traffic Selectors in the logs on both sides |

> **Warning**:
>
> Subnet mismatch is the most common cause of Phase 2 failure. The subnet mask must match exactly: `10.1.0.0/24` on one side and `10.1.0.0/24` on the other (not `10.1.0.0/23` or `10.1.0.0/32`).

### Phase 2 Encryption Parameter Mismatch

| Error Message | Cause | Solution |
|---|---|---|
| `NO_PROPOSAL_CHOSEN` (with Phase 1 established) | Phase 2 encryption algorithm or hash mismatch | Check Encryption Algorithm and Hash Algorithm in Phase 2 on both sides |
| `no acceptable ENCRYPTION_ALGORITHM found` | Proposed algorithm not supported | Agree on a common algorithm; AES-256-GCM or AES-256-CBC are the most compatible options |
| `no acceptable INTEGRITY_ALGORITHM found` | Hash Algorithm mismatch | Set the same Hash Algorithm in Phase 2 |

### PFS Mismatch

| Error Message | Cause | Solution |
|---|---|---|
| `no acceptable DIFFIE_HELLMAN_GROUP found` (in Phase 2) | PFS Group mismatch | Set the same PFS key group on both sides or disable PFS on both |
| `INVALID_KE_PAYLOAD` | Remote side sent a DH key of a different length | Check the PFS Group; one side may use Group 14, the other Group 2 |
| Phase 2 establishes but drops after one hour | PFS enabled on one side and disabled on the other | During rekeying, PFS parameters are re-checked; ensure they match or disable PFS on both sides |

### Tunnel Established but No Traffic

If Phase 1 and Phase 2 are established (status `Established`), but user traffic does not pass, the problem lies outside IPsec negotiation.

| Problem | Cause | Solution |
|---|---|---|
| No ping response through tunnel | Missing rules on the **Firewall > Rules > IPsec** tab | Create rules allowing traffic between subnets |
| Traffic flows in one direction only | Firewall rules configured for one direction only | Add rules for both directions on both sides |
| Response packets do not return | Asymmetric routing: return traffic bypasses the tunnel | Check the routing table on the remote side; ensure return traffic hits the Policy SPD |
| Packets are fragmented and lost | MTU issues due to IPsec overhead | Reduce MSS via **System > Advanced > Firewall & NAT** (MSS Clamping) or reduce MTU on interfaces |
| ICMP works, TCP hangs | MSS not adjusted for IPsec overhead | Enable MSS Clamping; IPsec adds 50-73 bytes to each packet |
| Duplicate SAs (two identical Child SAs) | Simultaneous rekeying by both sides | Restart the IPsec service on one side: `ipsec restart` |

## NAT-T Issues

NAT Traversal (NAT-T) is required when a NAT device (router, ISP equipment) sits between two IPsec tunnel endpoints. NAT-T encapsulates ESP packets in UDP port 4500, allowing them to pass through NAT.

### When NAT-T Is Required

- One or both IPsec endpoints are behind NAT (have a private IP address on the WAN interface)
- A router performing address translation sits between the endpoints
- The ISP uses Carrier-Grade NAT (CG-NAT)

### Common NAT-T Problems

| Problem | Cause | Solution |
|---|---|---|
| Phase 1 does not establish through NAT | NAT Traversal disabled | Set NAT Traversal to `Auto` or `Force` on both sides |
| Phase 1 establishes, Phase 2 does not | UDP 4500 blocked by intermediate equipment | Verify UDP 4500 port forwarding on the NAT device |
| `remote host is behind NAT` + identifier error | Peer identifier set to IP address, but NAT changed the address | Change Peer identifier to `Distinguished Name` or `User FQDN` |
| Periodic disconnections through NAT | NAT table on the intermediate device expires | Enable DPD with an interval shorter than the NAT table timeout (typically 60-300 seconds); ensure NAT keep-alive packets are being sent |
| Double NAT (NAT on both sides) | ESP cannot traverse two NAT devices without NAT-T | Enable Force NAT-T on both sides; ensure UDP 500 and 4500 are forwarded on both NAT devices |

### Verifying NAT-T

To verify NAT-T operation, perform a packet capture on the WAN interface:

```bash
# Capture IKE and NAT-T traffic
tcpdump -ni em0 udp port 500 or udp port 4500

# Expected output with NAT-T active:
# 10.0.0.1.4500 > 203.0.113.10.4500: UDP-encap: ESP(spi=0x12345678,seq=0x1)
```

If traffic is visible on port 4500 with the `UDP-encap: ESP` notation, NAT-T is functioning correctly. If traffic uses the ESP protocol (protocol 50) in the presence of NAT, the tunnel will be unstable.

## Diagnostic Commands

pfSense provides a set of commands for IPsec diagnostics via **Diagnostics > Command Prompt** or an SSH connection.

### IPsec SA Status

```bash
# Complete SA status with negotiated parameters
ipsec statusall

# Brief status (established tunnels only)
ipsec status

# View IP addresses assigned to mobile clients
ipsec leases
```

The `ipsec statusall` command displays:

- Negotiated encryption and hash algorithms
- DH and PFS groups
- Time until SA expiration
- Traffic Selectors (subnets)
- Byte counts
- Current IKE SA and Child SA status

### Security Policy Database (SPD)

```bash
# View installed security policies
setkey -DP

# View installed security associations
setkey -D
```

The `setkey -DP` command shows which packets should be processed by IPsec (routed into the tunnel). If a policy is missing for the required subnet pair, traffic will not be encrypted.

### Firewall Rules

```bash
# View all active firewall rules
pfctl -sr

# View rules for IPsec interface (enc0)
pfctl -sr | grep enc0

# View blocked packets in real time
tcpdump -ni pflog0
```

### Packet Capture

```bash
# Capture IKE negotiation on WAN
tcpdump -ni em0 udp port 500 or udp port 4500

# Capture ESP traffic (without NAT-T)
tcpdump -ni em0 proto 50

# Capture decrypted traffic on IPsec interface
tcpdump -ni enc0

# Capture with detailed output and write to file
tcpdump -ni em0 -vvv -s 0 -w /tmp/ipsec-capture.pcap udp port 500 or udp port 4500
```

Capturing on the `enc0` interface shows decrypted traffic inside the tunnel. This allows you to determine whether packets reach pfSense through the tunnel and in what form.

### Viewing Routes

```bash
# View routing table
netstat -rn

# Check if route for remote subnet exists
netstat -rn | grep "10.2.0.0"

# View gateway groups status
pfctl -vvsA
```

### Managing the IPsec Service

```bash
# Restart IPsec service (drops all tunnels)
ipsec restart

# Reload configuration without dropping tunnels
ipsec update

# Terminate specific IKE SA
ipsec down <connection_name>

# Re-initiate specific connection
ipsec up <connection_name>
```

> **Warning**:
>
> The `ipsec restart` command drops all active tunnels. In production environments, it is preferable to use `ipsec update` to apply configuration changes without disrupting existing connections.

## Rekeying Issues

IPsec tunnels have a limited lifetime. When this time expires, rekeying occurs - new keying material is negotiated. Errors during rekeying cause periodic tunnel disruptions.

| Problem | Cause | Solution |
|---|---|---|
| Tunnel drops every N hours | Rekeying error for Phase 1 or Phase 2 | Verify that Lifetime values match on both sides; check logs at the time of rekeying |
| Tunnel drops and does not recover | Child SA Start Action not configured | Set Child SA Start Action to `Start` for automatic reconnection |
| Duplicate SAs after rekeying | Both sides simultaneously initiate rekeying | Set different Lifetime values on each side (for example, 28800 and 28200 for Phase 1) or ensure Rand Time is not zeroed out |
| One-directional rekeying works, bidirectional does not | Settings are accepted when initiated from one side but not the other | All parameters must match; verify that no additional algorithms were added on one side |

## Diagnostic Checklist

When IPsec tunnel issues arise, it is recommended to work through the following checklist sequentially.

### 1. Network Connectivity

- [ ] Remote peer is reachable: `ping <remote_public_ip>`
- [ ] Route to remote peer exists: `traceroute <remote_public_ip>`
- [ ] UDP 500 is not blocked: `nc -uzv <remote_public_ip> 500`
- [ ] UDP 4500 is not blocked: `nc -uzv <remote_public_ip> 4500`

### 2. Phase 1 Parameters

- [ ] IKE version matches (IKEv1 or IKEv2)
- [ ] Encryption algorithm matches
- [ ] Hash Algorithm matches
- [ ] DH Group matches
- [ ] Lifetime matches (difference is tolerated; the lower value is used)
- [ ] Authentication method matches (PSK or certificates)
- [ ] PSK is identical on both sides (when using PSK)
- [ ] Identifiers (My/Peer) are configured correctly

### 3. Phase 2 Parameters

- [ ] Subnets (Traffic Selectors) match in mirror
- [ ] Subnet masks are correct (`/24` vs `/32`)
- [ ] Phase 2 Encryption Algorithm matches
- [ ] Phase 2 Hash Algorithm matches
- [ ] PFS Group matches or is disabled on both sides
- [ ] Protocol is ESP (not AH)

### 4. Certificates (When Used)

- [ ] CA certificate imported on both sides
- [ ] Server certificate has not expired (check the date)
- [ ] SAN in the server certificate contains the server IP or FQDN
- [ ] Certificate chain of trust is complete
- [ ] For Apple devices: server certificate Lifetime is no more than 825 days

### 5. Firewall Rules

- [ ] UDP 500 and 4500 are permitted on WAN
- [ ] Rules on the IPsec tab allow traffic between subnets
- [ ] No conflicting floating rules
- [ ] NAT Traversal is enabled (Auto or Force) when NAT is present

### 6. Routing and SA

- [ ] `ipsec statusall` shows established SAs
- [ ] `setkey -DP` contains policies for the required subnets
- [ ] `netstat -rn` contains a route to the remote subnet (for VTI)
- [ ] Byte counters in Status > IPsec increment when traffic passes

## Related Sections

- [IPsec Site-to-Site VPN in pfSense](/docs/pfsense/vpn/ipsec/pfsense-ipsec-site-to-site/) - configuring site-to-site tunnels, IPsec terminology, and Phase 1/Phase 2 parameters
- [IPsec IKEv2 for Mobile Clients in pfSense](/docs/pfsense/vpn/ipsec/pfsense-ipsec-mobile-clients/) - configuring IKEv2 for remote access, certificates, and client device setup
- [pfSense Firewall Rules](/docs/pfsense/firewall/pfsense-firewall-rules/) - principles of creating and managing firewall rules for VPN traffic
- [NAT in pfSense](/docs/pfsense/nat/) - NAT configuration, including the interaction between NAT and IPsec

