Skip to content

Error Handling System

Subnetter implements a comprehensive error handling system designed to provide clear, actionable information when something goes wrong. This document explains how the error system works, the different types of errors you might encounter, and how to interpret and resolve them.

Error Hierarchy

Subnetter uses a hierarchical error structure to organize errors by type:

SubnetterError (Base class)
├── ConfigurationError
├── AllocationError
├── ValidationError
├── IOError
└── CloudProviderError

Each error type provides specific context and help information relevant to its category.

Error Types

SubnetterError

The base error class for all Subnetter-specific errors. It provides:

  • Error message
  • Error code
  • Context information
  • Formatted error output
  • Help text

ConfigurationError

Indicates issues with the configuration file or settings. Common causes include:

  • Invalid JSON or YAML syntax
  • Missing required fields
  • Schema validation failures
  • Unsupported file formats

AllocationError

Signals problems with CIDR block allocation. Common causes include:

  • Insufficient address space for the requested allocation
  • Overlapping CIDR blocks
  • Invalid CIDR formats
  • Network conflicts

ValidationError

Represents input validation failures. Common causes include:

  • Invalid parameters passed to functions
  • Unsupported data formats
  • Type checking failures

IOError

Indicates file system operation failures. Common causes include:

  • File not found
  • Permission issues
  • Disk space problems
  • Network connectivity issues when accessing remote files

CloudProviderError

Represents cloud provider-specific issues. Common causes include:

  • Unsupported cloud providers
  • Invalid region or zone names
  • Provider-specific limitations

Error Codes

Each error includes a specific error code that helps identify the exact issue. Error codes follow this pattern:

  • E1xxx: General errors
  • E2xxx: Configuration errors
  • E3xxx: CIDR allocation errors
  • E4xxx: I/O errors
  • E5xxx: Cloud provider errors

Examples:

Error CodeDescription
E1001Unknown error
E2001Invalid configuration format
E2002Configuration validation failed
E2003Configuration file not found
E3001Insufficient address space
E3002CIDR blocks overlap
E3003Invalid CIDR format
E4001File not found
E4002Permission denied
E5001Unsupported cloud provider

Error Messages

Error messages follow a consistent format:

ERROR [E3001] Insufficient address space: No CIDR available for region us-east-1 at index 0

When context is available, it’s displayed in a structured format:

ERROR [E3001] Insufficient address space: No CIDR available for region us-east-1 at index 0
Context:
- Account: production
- Regions: us-east-1, us-west-2
- Base CIDR: 10.0.0.0/24 (too small for the requested allocation)

Reading Error Messages

When you encounter an error, follow these steps to interpret it:

  1. Identify the error type (ConfigurationError, AllocationError, etc.)
  2. Note the error code (E1xxx, E2xxx, etc.)
  3. Read the error message for a description of the issue
  4. Check the context information for specific details
  5. Refer to the help text for suggested solutions

Common Error Scenarios and Solutions

Configuration Errors

Invalid JSON/YAML Format

ERROR [E2001] Invalid configuration format: Unexpected token } in JSON at position 105

Solution: Check your JSON or YAML syntax. Common issues include missing commas, unbalanced braces, and quote mismatches.

Missing Required Fields

ERROR [E2002] Configuration validation failed: Missing required field 'accounts'

Solution: Ensure your configuration includes all required fields. See the Configuration Format documentation for details.

Unsupported File Format

ERROR [E2005] Unsupported file extension: .txt. Supported formats are: .json, .yaml, .yml

Solution: Use one of the supported file formats (JSON or YAML).

Allocation Errors

Insufficient Address Space

ERROR [E3001] Insufficient address space: No CIDR available for region us-east-1

Solution:

  • Use a larger base CIDR (smaller prefix length)
  • Reduce the number of regions or subnets
  • Adjust the prefix lengths for different levels of the hierarchy

Overlapping CIDRs

ERROR [E3002] CIDR blocks overlap: 10.0.0.0/24 overlaps with 10.0.0.128/25

Solution: Ensure that manually specified CIDRs don’t overlap with each other or with automatically allocated CIDRs.

Invalid CIDR Format

ERROR [E3003] Invalid CIDR format: 10.0.0/8

Solution: Use the correct CIDR notation (e.g., 10.0.0.0/8).

I/O Errors

File Not Found

ERROR [E4001] File not found: /path/to/config.json

Solution: Check the file path and ensure the file exists.

Permission Denied

ERROR [E4002] Permission denied when reading file: /path/to/config.json

Solution: Check file permissions and ensure your user account has read access.

Using Error Handling Programmatically

If you’re using Subnetter as a library in your own application, you can catch and handle specific error types:

import {
SubnetterError,
ConfigurationError,
AllocationError,
CloudProviderError,
ValidationError,
IOError,
ErrorCode
} from '@subnetter/core';
try {
const allocations = cidrAllocator.generateAllocations(config);
} catch (error) {
if (error instanceof ConfigurationError) {
console.error('Configuration problem:', error.message);
console.log('Help:', error.getHelpText());
} else if (error instanceof AllocationError) {
console.error('Allocation failure:', error.message);
console.log('Context:', error.getContextString());
} else if (error instanceof CloudProviderError) {
console.error('Cloud provider issue:', error.message);
console.log('Provider help:', error.getHelpText());
// You might want to handle specific cloud provider errors
if (error.code === ErrorCode.INVALID_CLOUD_PROVIDER) {
console.error('Unsupported cloud provider specified');
} else if (error.code === ErrorCode.INVALID_REGION) {
console.error('Invalid region specified for the cloud provider');
}
} else if (error instanceof ValidationError) {
console.error('Validation error:', error.message);
} else if (error instanceof IOError) {
console.error('I/O operation failed:', error.message);
} else if (error instanceof SubnetterError) {
console.error(`Error [${error.code}]:`, error.message);
} else {
console.error('Unknown error:', error);
}
}

This allows you to provide custom error handling and recovery strategies based on the type of error encountered.

Adding Custom Error Types

If you’re extending Subnetter and need to add custom error types, you can extend the SubnetterError class:

import { SubnetterError, ErrorCode } from '@subnetter/core';
export class CustomError extends SubnetterError {
constructor(message: string, code: ErrorCode = ErrorCode.UNKNOWN_ERROR, context?: Record<string, any>) {
super(message, code, context);
this.name = 'CustomError';
}
getHelpText(): string {
return 'This is a custom error. Here are steps to resolve it...';
}
}

CIDR Allocation Errors

Errors related to CIDR allocation are among the most common issues when using Subnetter. This section covers the most frequent allocation errors, their causes, and how to resolve them.

Error Code 3001: Invalid CIDR Format

Error Message: Invalid CIDR format: {cidr}

Cause: The CIDR notation provided does not follow the standard format (e.g., 10.0.0.0/8). This error commonly occurs in:

  • Base CIDR definitions
  • Account-level CIDR overrides
  • Cloud provider CIDR overrides

Resolution:

  1. Check the CIDR syntax to ensure it follows the format IP_ADDRESS/PREFIX_LENGTH
  2. Verify that the IP address is valid (e.g., 10.0.0.0, not 10.0.0.256)
  3. Ensure the prefix length is between 0 and 32
// ❌ Invalid
"baseCidr": "10.0.0/8" // Missing an octet
// ✅ Valid
"baseCidr": "10.0.0.0/8"

Error Code 3002: Not Enough Space

Error Message: Not enough space left for allocation with prefix /{prefix}

Cause: The allocator attempted to allocate a CIDR block, but there wasn’t enough space left in the parent CIDR. This commonly occurs when:

  • The base CIDR is too small for the number of allocations requested
  • The prefix lengths are too small (resulting in larger subnets)
  • There are too many accounts, regions, AZs, or subnet types configured

Resolution:

  1. Use a larger base CIDR (e.g., change from /16 to /8)
  2. Reduce the number of accounts, regions, or AZs
  3. Use larger prefix lengths for subnet types (e.g., change from /24 to /26)
  4. Split your configuration into multiple separate configurations

Example Fix:

// ❌ Problem: Base CIDR too small
{
"baseCidr": "10.0.0.0/16", // Only 65,536 addresses
"accounts": [
// 10 accounts, each needing a /20 (4,096 addresses)
// 10 * 4,096 = 40,960 addresses (fits in /16)
// But with regions, AZs, and subnets, it's not enough
]
}
// ✅ Solution: Use larger base CIDR
{
"baseCidr": "10.0.0.0/12", // 1,048,576 addresses (16x more space)
"accounts": [
// Same 10 accounts, but now with plenty of space
]
}

Error Code 3003: Subnet Type Not Found

Error Message: Subnet type '{type}' not found in configuration

Cause: A subnet type referenced in the allocation process wasn’t defined in the subnetTypes section of the configuration.

Resolution:

  1. Add the missing subnet type to your configuration
  2. Check for typos in subnet type names (they are case-sensitive)
// ❌ Missing subnet type
{
"subnetTypes": {
"Public": 26,
"Private": 26
// "Database" is missing but used elsewhere
}
}
// ✅ Corrected
{
"subnetTypes": {
"Public": 26,
"Private": 26,
"Database": 26
}
}

Error Code 3004: CIDR Block Overlap

Error Message: CIDR block '{cidr1}' overlaps with '{cidr2}'

Cause: Two allocated CIDR blocks overlap, which would create routing conflicts. This commonly occurs when:

  • Custom CIDR overrides are used at different levels
  • Manual CIDR ranges are provided that overlap

Resolution:

  1. Ensure that manually specified CIDRs do not overlap
  2. Let Subnetter handle allocation automatically if possible
  3. Use CIDR calculators to check for overlaps before specifying custom ranges
// ❌ Overlapping CIDRs
{
"accounts": [
{
"name": "prod",
"clouds": {
"aws": {
"provider": "aws",
"baseCidr": "10.0.0.0/16"
}
}
},
{
"name": "staging",
"clouds": {
"aws": {
"provider": "aws",
"baseCidr": "10.0.128.0/17" // Overlaps with prod (10.0.0.0/16)
}
}
}
]
}
// ✅ Non-overlapping CIDRs
{
"accounts": [
{
"name": "prod",
"clouds": {
"aws": {
"provider": "aws",
"baseCidr": "10.0.0.0/16"
}
}
},
{
"name": "staging",
"clouds": {
"aws": {
"provider": "aws",
"baseCidr": "10.1.0.0/16" // No overlap (different /16 block)
}
}
}
]
}

Error Code 3005: Invalid Prefix Length

Error Message: Invalid prefix length: {prefix}. Must be between 0 and 32.

Cause: A prefix length specified in the configuration is outside the valid range.

Resolution:

  1. Ensure all prefix lengths are between 0 and 32
  2. Check for typos or missing values
// ❌ Invalid prefix length
{
"subnetTypes": {
"Public": 26,
"Private": 33, // Invalid - must be <= 32
"Database": -1 // Invalid - must be >= 0
}
}
// ✅ Valid prefix lengths
{
"subnetTypes": {
"Public": 26,
"Private": 26,
"Database": 27
}
}

Error Code 3006: Inconsistent Prefix Hierarchy

Error Message: Inconsistent prefix hierarchy: {level1} prefix ({prefix1}) must be less than {level2} prefix ({prefix2})

Cause: The prefix lengths in the hierarchy are inconsistent. For example, an account prefix is larger than a region prefix, which would result in regions being larger than accounts.

Resolution:

  1. Ensure that prefix lengths increase as you move down the hierarchy:
    • Base CIDR prefix < Account prefix < Region prefix < AZ prefix < Subnet prefix
  2. Adjust prefix lengths to maintain this hierarchy
// ❌ Inconsistent prefix hierarchy
{
"prefixLengths": {
"account": 24, // Account subnets are /24 (256 addresses)
"region": 20, // Region subnets are /20 (4,096 addresses) - WRONG!
"az": 28 // AZ subnets are /28 (16 addresses)
}
}
// ✅ Consistent prefix hierarchy
{
"prefixLengths": {
"account": 16, // Account subnets are /16 (65,536 addresses)
"region": 20, // Region subnets are /20 (4,096 addresses)
"az": 24 // AZ subnets are /24 (256 addresses)
}
}

Error Code 3007: Invalid IP Address

Error Message: Invalid IP address: {ip}

Cause: An IP address in the CIDR notation is malformed or contains invalid values.

Resolution:

  1. Ensure each octet of the IP address is between 0 and 255
  2. Check for typos or malformed addresses
// ❌ Invalid IP addresses
"baseCidr": "10.0.0.256/16" // 256 is not valid (must be <= 255)
"baseCidr": "10.0.0/16" // Missing an octet
"baseCidr": "10.0.0.0.0/16" // Too many octets
// ✅ Valid IP addresses
"baseCidr": "10.0.0.0/16"
"baseCidr": "192.168.1.0/24"

Troubleshooting CIDR Allocation

If you’re experiencing CIDR allocation issues, try these troubleshooting steps:

  1. Verify Configuration: Run validation on your configuration without generating allocations:

    Terminal window
    subnetter validate -c config.json
  2. Check Space Requirements: Use a CIDR calculator to estimate your space needs:

    Number of Accounts × Number of Regions × Number of AZs × Number of Subnet Types × Subnet Size
  3. Simplify and Incrementally Add: Start with a minimal configuration and gradually add components:

    Terminal window
    # Start with 1 account, 1 region, basic subnet types
    subnetter generate -c simple-config.json
    # Gradually add more accounts, regions, etc.
  4. Log Detailed Allocation: Enable debug mode to see detailed allocation steps:

    Terminal window
    subnetter generate -c config.json --debug
  5. Validate CIDR Overrides: If using custom CIDR overrides, verify they don’t overlap:

    Terminal window
    # Check each override with a tool like ipcalc
    ipcalc 10.0.0.0/16 10.0.128.0/17

Common Allocation Scenarios and Solutions

Scenario 1: Too Many Accounts for Available Space

Problem: Your base CIDR is too small for the number of accounts you’re trying to allocate.

Solution:

  1. Use a larger base CIDR
  2. Use individual baseCidr overrides for each account
  3. Increase the account prefix (smaller allocations)

Scenario 2: Regional Expansion

Problem: You need to add new regions, but don’t have enough space left.

Solution:

  1. Reserve space for future regions during initial allocation
  2. Use explicit CIDR overrides for new regions
  3. Create a separate configuration for new regions

Scenario 3: Multi-Cloud Allocation

Problem: You need to allocate separate non-overlapping CIDR blocks for different cloud providers.

Solution:

  1. Use different RFC1918 ranges for different clouds:
    • AWS: 10.0.0.0/8
    • Azure: 172.16.0.0/12
    • GCP: 192.168.0.0/16
  2. Configure cloud-specific overrides:
    "clouds": {
    "aws": {
    "provider": "aws",
    "baseCidr": "10.0.0.0/8"
    },
    "azure": {
    "provider": "azure",
    "baseCidr": "172.16.0.0/12"
    }
    }

Scenario 4: Need Larger Subnets for Specific Types

Problem: Some subnet types (like container subnets) need more IP addresses than others.

Solution:

  1. Adjust subnet type prefix lengths:
    "subnetTypes": {
    "Public": 26, // 62 usable IPs
    "PrivateWebTier": 25, // 126 usable IPs
    "PrivateAppTier": 24, // 254 usable IPs
    "ContainerTier": 20, // 4,094 usable IPs
    "PrivateDataTier": 26 // 62 usable IPs
    }
  2. Consider using larger CIDR blocks at the region level to accommodate larger subnet types

Conclusion

Subnetter’s error handling system is designed to provide clear, actionable information when something goes wrong. By understanding the different error types and their causes, you can quickly diagnose and resolve issues with your CIDR allocations.