What's Actually Happening

HashiCorp Boundary fails to establish sessions to targets. Users cannot connect to infrastructure resources through Boundary.

The Error You'll See

Session failed:

```bash $ boundary connect -target-id ttcp_123456789

Error: error creating session: failed to authorize session ```

Worker unavailable:

bash
Error: no workers available for target

Connection timeout:

bash
Error: connection timed out: unable to establish session

Authentication error:

bash
Error: error authenticating: permission denied

Why This Happens

  1. 1.Worker issues - Boundary workers down or unreachable
  2. 2.Target misconfiguration - Invalid target address or port
  3. 3.Permission denied - User lacks access to target
  4. 4.Network connectivity - Workers cannot reach targets
  5. 5.Authentication expired - Token needs refresh
  6. 6.Host catalog issues - Host sets or catalogs misconfigured

Step 1: Check Boundary Status

```bash # Check Boundary server: boundary version

# Check controller status: boundary status

# List available scopes: boundary scopes list

# Check authentication: boundary authenticate password -login-name=admin

# Check current user: boundary users read -id <user-id>

# Check session limit: boundary config read ```

Step 2: Check Worker Status

```bash # List workers: boundary workers list

# Check worker status: boundary workers read -id <worker-id>

# Check worker is online: # Status should be "online"

# Check worker tags: boundary workers read -id <worker-id> -format=json | jq '.item.tags'

# Worker must have appropriate tags for target

# Check worker logs: journalctl -u boundary-worker -n 50

# For Kubernetes: kubectl logs -n boundary deployment/boundary-worker

# Restart worker if needed: systemctl restart boundary-worker ```

Step 3: Check Target Configuration

```bash # List targets: boundary targets list -scope-id <scope-id>

# Read target details: boundary targets read -id <target-id>

# Check target type: # - tcp (standard TCP) # - ssh # - rdp

# Check target address: boundary targets read -id <target-id> -format=json | jq '.item.attributes.value.destination'

# Should be valid IP or hostname

# Check default port: boundary targets read -id <target-id> -format=json | jq '.item.attributes.value.port'

# Update target if needed: boundary targets update tcp \ -id <target-id> \ -default-port 22 \ -default-host-catalog-id <catalog-id> \ -default-host-set-id <host-set-id> ```

Step 4: Check Host Catalog

```bash # List host catalogs: boundary host-catalogs list -scope-id <scope-id>

# Read host catalog: boundary host-catalogs read -id <catalog-id>

# List host sets: boundary host-sets list -host-catalog-id <catalog-id>

# Read host set: boundary host-sets read -id <host-set-id>

# Check hosts in set: boundary hosts list -host-set-id <host-set-id>

# For static host catalog: boundary hosts read -id <host-id>

# Verify host address: boundary hosts read -id <host-id> -format=json | jq '.item.attributes.value.address'

# Test connectivity from worker: ping <host-address> nc -zv <host-address> <port> ```

Step 5: Check Permissions

```bash # Check user roles: boundary roles list -scope-id <scope-id>

# Read user roles: boundary users read -id <user-id> -format=json | jq '.item.roles'

# Check role grants: boundary roles read -id <role-id>

# Required grants for session: # - type=target;id=<target-id>;actions=authorize-session

# Check group membership: boundary groups list -scope-id <scope-id>

# Add user to role: boundary roles add-principals \ -id <role-id> \ -principal <user-id>

# Create role with session grant: boundary roles create \ -scope-id <scope-id> \ -name "session-role" \ -grant "id=<target-id>;type=target;actions=authorize-session" ```

Step 6: Test Connectivity

```bash # Test worker to target connectivity:

# SSH into worker host: ssh boundary-worker-host

# Test target connectivity: nc -zv <target-address> <port>

# Check firewall: iptables -L -n | grep <port>

# Allow port: iptables -I INPUT -p tcp --dport <port> -j ACCEPT

# Check DNS: nslookup <target-hostname>

# Test from worker process: boundary-worker --test-connectivity <target-address>:<port>

# Check worker network configuration: ip route ip addr ```

Step 7: Check Authentication

```bash # Check auth methods: boundary auth-methods list -scope-id global

# Read auth method: boundary auth-methods read -id <auth-method-id>

# For password auth: boundary authenticate password \ -login-name <username> \ -password <password>

# For OIDC: boundary authenticate oidc \ -auth-method-id <auth-method-id>

# Check token validity: boundary scopes list -format=json | jq .

# If token expired, re-authenticate: boundary authenticate password -login-name <username>

# Check auth token TTL: boundary config read -format=json | jq '.item.auth_token_time_to_live' ```

Step 8: Check Session Logs

```bash # Check Boundary controller logs: journalctl -u boundary-controller -f

# Check for session errors: journalctl -u boundary-controller | grep -i "session|error|failed"

# Check worker logs: journalctl -u boundary-worker | grep -i "session|connection|error"

# Common errors: # - "worker not found" # - "target unreachable" # - "permission denied" # - "connection refused"

# Enable debug logging: # In controller config: log_level = "debug"

# Restart controller: systemctl restart boundary-controller ```

Step 9: Configure Worker Tags

```bash # Worker tags must match target worker filter:

# Check target worker filter: boundary targets read -id <target-id> -format=json | jq '.item.worker_filter'

# Example filter: # "type" in "/tags/environment"

# Add tags to worker: # In worker config: listener "tcp" { address = "0.0.0.0:9202" purpose = "proxy" }

worker { tags { type = ["aws", "production"] environment = ["prod"] } }

# Restart worker: systemctl restart boundary-worker

# Verify tags: boundary workers read -id <worker-id> -format=json | jq '.item.tags' ```

Step 10: Monitor Sessions

```bash # Create monitoring script: cat << 'EOF' > /usr/local/bin/monitor-boundary.sh #!/bin/bash

echo "=== Workers ===" boundary workers list -format=json | jq '.[] | {id: .id, status: .status}'

echo "" echo "=== Active Sessions ===" boundary sessions list -format=json | jq '.[] | {id: .id, status: .status, target_id: .target_id}'

echo "" echo "=== Recent Session Errors ===" journalctl -u boundary-controller --since "1 hour ago" | grep -i "session.*error|failed"

echo "" echo "=== Worker Connectivity ===" for worker in $(boundary workers list -format=json | jq -r '.[].id'); do echo "Worker $worker:" boundary workers read -id $worker -format=json | jq '{status: .status, last_status_change: .item.last_status_change}' done EOF

chmod +x /usr/local/bin/monitor-boundary.sh

# Prometheus metrics (if configured): curl http://localhost:9203/metrics | grep boundary

# Key metrics: # boundary_session_total # boundary_session_errors # boundary_worker_status

# Alerts: - alert: BoundaryWorkerOffline expr: boundary_worker_status == 0 for: 5m labels: severity: critical annotations: summary: "Boundary worker offline" ```

Boundary Session Failed Checklist

CheckCommandExpected
Worker statusworkers listOnline
Target configtargets readValid address
Host cataloghosts listHosts exist
Permissionsroles readHas authorize-session
Connectivitync -zvConnected
AuthenticationauthenticateSuccess

Verify the Fix

```bash # After fixing session issue

# 1. Test authentication boundary authenticate password -login-name admin // Authentication successful

# 2. Check worker boundary workers list // Workers online

# 3. Test session boundary connect -target-id <target-id> // Session established

# 4. Verify connection # Connected to target via Boundary proxy

# 5. Check session status boundary sessions list // Session active

# 6. Monitor logs journalctl -u boundary-worker -f // No errors ```

  • [Fix Vault Token Renewal Failed](/articles/fix-vault-token-renewal-failed)
  • [Fix Keycloak User Login Failed](/articles/fix-keycloak-user-login-failed)
  • [Fix Consul Agent Not Starting](/articles/fix-consul-agent-not-starting)