Introduction
AWS WAF IP sets store lists of IP addresses used in web ACL rules. When updating an IP set fails, your security rules can't use the latest IP addresses, potentially blocking legitimate traffic or allowing unauthorized access.
Symptoms
Update failed:
```bash $ aws wafv2 update-ip-set \ --scope REGIONAL \ --id IP_SET_ID \ --name my-ip-set \ --addresses "1.2.3.4/32" "5.6.7.8/32"
An error occurred (WAFOptimisticLockException) when calling the UpdateIPSet operation: AWS WAF couldn't save your changes because the resource was modified by another user/process. ```
Capacity exceeded:
An error occurred (WAFInvalidParameterException) when calling the UpdateIPSet operation: The IP set exceeds capacity limitsIP set not found:
An error occurred (WAFNonexistentItemException) when calling the UpdateIPSet operation: AWS WAF couldn't find the resourceCommon Causes
- 1.Optimistic lock conflict - Concurrent updates without proper lock token
- 2.Capacity limit exceeded - Too many IP addresses in set
- 3.Wrong scope - Regional vs CloudFront scope mismatch
- 4.Invalid IP format - Incorrect CIDR notation
- 5.IP set used in active rules - Rules referencing IP set during update
- 6.Rate limiting - Too many updates in short time
- 7.Wrong LockToken - Stale lock token from previous operation
Step-by-Step Fix
- 1.Check logs for specific error messages
- 2.Verify configuration settings
- 3.Test network connectivity
- 4.Review recent changes
- 5.Apply corrective action
- 6.Verify the fix
Step 1: Get Current IP Set State
```bash # Get IP set details with lock token aws wafv2 get-ip-set \ --scope REGIONAL \ --name my-ip-set \ --id IP_SET_ID
# Note the LockToken value for update operations { "IPSet": { "Name": "my-ip-set", "Id": "abc-123", "ARN": "arn:aws:wafv2:...", "IPAddressVersion": "IPV4", "Addresses": ["10.0.0.0/8"] }, "LockToken": "abc123def456" } ```
Step 2: Use Correct Lock Token
```bash # First, get the current lock token LOCK_TOKEN=$(aws wafv2 get-ip-set \ --scope REGIONAL \ --name my-ip-set \ --id IP_SET_ID \ --query 'LockToken' --output text)
# Then use it in update aws wafv2 update-ip-set \ --scope REGIONAL \ --name my-ip-set \ --id IP_SET_ID \ --lock-token $LOCK_TOKEN \ --addresses "1.2.3.4/32" "5.6.7.8/32"
# Returns new lock token for next update ```
Step 3: Check Capacity Limits
```bash # Get current capacity aws wafv2 get-ip-set \ --scope REGIONAL \ --name my-ip-set \ --id IP_SET_ID \ --query 'IPSet.Addresses'
# WAF IP set limits: # - 10,000 IP addresses per set (regular) # - 150,000 addresses (for IP sets used in rate-based rules)
# Count current addresses aws wafv2 get-ip-set --scope REGIONAL --name my-ip-set --id IP_SET_ID \ --query 'length(IPSet.Addresses)'
# If approaching limit, split into multiple IP sets ```
Step 4: Create Additional IP Sets for Large Lists
```bash # Create additional IP set for overflow aws wafv2 create-ip-set \ --scope REGIONAL \ --name my-ip-set-extended \ --ip-address-version IPV4 \ --addresses "100.0.0.0/16" "101.0.0.0/16"
# Reference both IP sets in your rules ```
Step 5: Verify IP Address Format
```bash # Correct formats: # IPv4: "1.2.3.4/32" (single IP) # IPv4: "10.0.0.0/8" (CIDR range) # IPv6: "2001:db8::/32"
# Common format errors: # - Missing CIDR notation: "1.2.3.4" (wrong) vs "1.2.3.4/32" (correct) # - Wrong prefix: "1.2.3.4/24" for single IP (should be /32)
# Validate before update for ip in "1.2.3.4/32" "10.0.0.0/8"; do if [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$ ]]; then echo "$ip is valid IPv4 CIDR" fi done ```
Step 6: Handle Concurrent Updates
```bash # Script to handle lock conflicts with retry #!/bin/bash IP_SET_ID="abc-123" IP_SET_NAME="my-ip-set"
update_ip_set() { local addresses="$1" local max_attempts=5 local attempt=1
while [ $attempt -le $max_attempts ]; do # Get current lock token LOCK_TOKEN=$(aws wafv2 get-ip-set \ --scope REGIONAL \ --name $IP_SET_NAME \ --id $IP_SET_ID \ --query 'LockToken' --output text)
# Attempt update if aws wafv2 update-ip-set \ --scope REGIONAL \ --name $IP_SET_NAME \ --id $IP_SET_ID \ --lock-token $LOCK_TOKEN \ --addresses $addresses; then echo "Update successful" return 0 fi
echo "Attempt $attempt failed, retrying..." sleep 2 attempt=$((attempt + 1)) done
echo "Failed after $max_attempts attempts" return 1 }
update_ip_set '"1.2.3.4/32" "5.6.7.8/32"' ```
Step 7: Check Scope Mismatch
```bash # WAF has two scopes: # - REGIONAL: For ALB, API Gateway, AppSync # - CLOUDFRONT: For CloudFront distributions
# Check IP set scope aws wafv2 list-ip-sets --scope REGIONAL aws wafv2 list-ip-sets --scope CLOUDFRONT
# Must use matching scope in commands # Regional IP set cannot be used with CloudFront
# Get correct ID for scope aws wafv2 get-ip-set \ --scope REGIONAL \ --name my-ip-set \ --id IP_SET_ID ```
Step 8: Update IP Set Referenced by Rules
```bash # IP sets can be updated even when referenced by rules # But check if web ACL needs update after IP set change
# List web ACLs using the IP set aws wafv2 list-web-acls --scope REGIONAL
# Get web ACL details aws wafv2 get-web-acl \ --scope REGIONAL \ --name my-web-acl \ --id WEB_ACL_ID \ --query 'WebACL.Rules[?Statement.IPSetReferenceStatement]'
# No need to update web ACL after IP set update # Changes propagate automatically ```
Step 9: Check for Propagation Delays
```bash # Changes take time to propagate # Regional: ~1 minute # CloudFront: ~5-10 minutes
# Wait after update before testing sleep 60
# Test rule behavior curl -H "X-Forwarded-For: 1.2.3.4" https://my-alb.example.com
# Check WAF logs for rule matches aws logs filter-log-events \ --log-group-name aws-waf-logs-my-acl \ --filter-pattern "1.2.3.4" ```
Step 10: Use Batch Updates for Large Changes
```bash # For large IP sets, update in batches # Get current addresses CURRENT=$(aws wafv2 get-ip-set \ --scope REGIONAL \ --name my-ip-set \ --id IP_SET_ID \ --query 'IPSet.Addresses' --output json)
# Add new addresses to existing NEW_ADDRESSES=$(echo $CURRENT | jq '. + ["11.0.0.0/8"]')
# Update with combined list LOCK_TOKEN=$(aws wafv2 get-ip-set \ --scope REGIONAL \ --name my-ip-set \ --id IP_SET_ID \ --query 'LockToken' --output text)
aws wafv2 update-ip-set \ --scope REGIONAL \ --name my-ip-set \ --id IP_SET_ID \ --lock-token $LOCK_TOKEN \ --addresses "$NEW_ADDRESSES" ```
IP Set Update Workflow
- 1.Get current IP set state and LockToken
- 2.Prepare new address list
- 3.Call update-ip-set with LockToken
- 4.Handle WAFOptimisticLockException with retry
- 5.Wait for propagation (1-10 minutes)
- 6.Verify changes applied
Verification
```bash # After update, verify addresses aws wafv2 get-ip-set \ --scope REGIONAL \ --name my-ip-set \ --id IP_SET_ID \ --query 'IPSet.Addresses'
# Should show new addresses
# Test rule is blocking/allowing as expected # Check WAF logs aws logs filter-log-events \ --log-group-name aws-waf-logs-my-acl \ --start-time $(date -d '10 minutes ago' +%s)000 ```
Related Issues
- [Fix AWS WAF Rule Not Matching](/articles/fix-aws-waf-ip-set-not-updating)
- [Fix AWS CloudFront Distribution Not Working](/articles/fix-cloudflare-521-web-server-down)
- [Fix AWS ELB Health Check Failing](/articles/fix-aws-elb-health-check-failing)
Related Articles
- [AWS troubleshooting: Fix IAM Permission Denied - Complete Tro](fix-iam-permission-denied)
- [AWS cloud troubleshooting: AWS ACM Certificate Pending Validation Because the](aws-acm-certificate-pending-validation-wrong-route53-zone)
- [AWS cloud troubleshooting: AWS ALB Returns 502 Because the Target Closed the ](aws-alb-502-target-closed-connection-keepalive-timeout-mismatch)
- [AWS cloud troubleshooting: Fix AWS ALB CreateListener TargetGroupNotFound Err](aws-alb-createlistener-targetgroupnotfound)
- [AWS cloud troubleshooting: Fix Aws Alb Lambda 502 Bad Gateway Issue in AWS](aws-alb-lambda-502-bad-gateway)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix AWS WAF IP Set Not Updating", "description": "Troubleshoot WAF IP set update failures. Fix lock conflicts, capacity issues, and API usage for IP address management.", "url": "https://www.fixwikihub.com/fix-aws-waf-ip-set-not-updating", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-02T01:56:52.839Z", "dateModified": "2026-04-02T01:56:52.839Z" } </script>