Claude
Skills
Sign in
โ† Back

adf-validation-rules

Included with Lifetime
$97 forever

ADF activity nesting rules, limits, and validation gotchas. PROACTIVELY activate for: (1) ADF activity nesting rules (ForEach inside If, Switch, Until), (2) ForEach limitations (no nested ForEach, item limits), (3) pipeline validation errors and ARM-template build failures, (4) linked service authentication issues, (5) Set Variable restrictions in ForEach, (6) Data Flow constraints (transformation limits, source/sink rules), (7) parameter and variable scope, (8) max activities per pipeline, (9) pipeline concurrency limits. Provides: nesting rule matrix, activity limit reference, validation error catalog, and refactoring patterns for unsupported nesting.

General

What this skill does


# Azure Data Factory Validation Rules and Limitations

## ๐Ÿšจ CRITICAL: Activity Nesting Limitations

Azure Data Factory has **STRICT** nesting rules for control flow activities. Violating these rules will cause pipeline failures or prevent pipeline creation.

### Supported Control Flow Activities for Nesting

Four control flow activities support nested activities:
- **ForEach**: Iterates over collections and executes activities in a loop
- **If Condition**: Branches based on true/false evaluation
- **Until**: Implements do-until loops with timeout options
- **Switch**: Evaluates activities matching case conditions

### โœ… PERMITTED Nesting Combinations

| Parent Activity | Can Contain | Notes |
|----------------|-------------|-------|
| **ForEach** | If Condition | โœ… Allowed |
| **ForEach** | Switch | โœ… Allowed |
| **Until** | If Condition | โœ… Allowed |
| **Until** | Switch | โœ… Allowed |

### โŒ PROHIBITED Nesting Combinations

| Parent Activity | CANNOT Contain | Reason |
|----------------|----------------|---------|
| **If Condition** | ForEach | โŒ Not supported - use Execute Pipeline workaround |
| **If Condition** | Switch | โŒ Not supported - use Execute Pipeline workaround |
| **If Condition** | Until | โŒ Not supported - use Execute Pipeline workaround |
| **If Condition** | Another If | โŒ Cannot nest If within If |
| **Switch** | ForEach | โŒ Not supported - use Execute Pipeline workaround |
| **Switch** | If Condition | โŒ Not supported - use Execute Pipeline workaround |
| **Switch** | Until | โŒ Not supported - use Execute Pipeline workaround |
| **Switch** | Another Switch | โŒ Cannot nest Switch within Switch |
| **ForEach** | Another ForEach | โŒ Single level only - use Execute Pipeline workaround |
| **Until** | Another Until | โŒ Single level only - use Execute Pipeline workaround |
| **ForEach** | Until | โŒ Single level only - use Execute Pipeline workaround |
| **Until** | ForEach | โŒ Single level only - use Execute Pipeline workaround |

### ๐Ÿšซ Special Activity Restrictions

**Validation Activity**:
- โŒ **CANNOT** be placed inside ANY nested activity
- โŒ **CANNOT** be used within ForEach, If, Switch, or Until activities
- โœ… Must be at pipeline root level only

### ๐Ÿ”ง Workaround: Execute Pipeline Pattern

**The ONLY supported workaround for prohibited nesting combinations:**

Instead of direct nesting, use the **Execute Pipeline Activity** to call a child pipeline:

```json
{
  "name": "ParentPipeline_WithIfCondition",
  "activities": [
    {
      "name": "IfCondition_Parent",
      "type": "IfCondition",
      "typeProperties": {
        "expression": "@equals(pipeline().parameters.ProcessData, 'true')",
        "ifTrueActivities": [
          {
            "name": "ExecuteChildPipeline_WithForEach",
            "type": "ExecutePipeline",
            "typeProperties": {
              "pipeline": {
                "referenceName": "ChildPipeline_ForEachLoop",
                "type": "PipelineReference"
              },
              "parameters": {
                "ItemList": "@pipeline().parameters.Items"
              }
            }
          }
        ]
      }
    }
  ]
}
```

**Child Pipeline Structure:**
```json
{
  "name": "ChildPipeline_ForEachLoop",
  "parameters": {
    "ItemList": {"type": "array"}
  },
  "activities": [
    {
      "name": "ForEach_InChildPipeline",
      "type": "ForEach",
      "typeProperties": {
        "items": "@pipeline().parameters.ItemList",
        "activities": [
          // Your ForEach logic here
        ]
      }
    }
  ]
}
```

**Why This Works:**
- Each pipeline can have ONE level of nesting
- Execute Pipeline creates a new pipeline context
- Child pipeline gets its own nesting level allowance
- Enables unlimited depth through pipeline chaining

## ๐Ÿ”ข Activity and Resource Limits

### Pipeline Limits
| Resource | Limit | Notes |
|----------|-------|-------|
| **Activities per pipeline** | 80 | Includes inner activities for containers |
| **Parameters per pipeline** | 50 | - |
| **ForEach concurrent iterations** | 50 (maximum) | Set via `batchCount` property |
| **ForEach items** | 100,000 | - |
| **Lookup activity rows** | 5,000 | Maximum rows returned |
| **Lookup activity size** | 4 MB | Maximum size of returned data |
| **Web activity timeout** | 1 hour | Default timeout for Web activities |
| **Copy activity timeout** | 7 days | Maximum execution time |

### ForEach Activity Configuration
```json
{
  "name": "ForEachActivity",
  "type": "ForEach",
  "typeProperties": {
    "items": "@pipeline().parameters.ItemList",
    "isSequential": false,  // false = parallel execution
    "batchCount": 50,       // Max 50 concurrent iterations
    "activities": [
      // Nested activities
    ]
  }
}
```

**Critical Considerations:**
- `isSequential: true` โ†’ Executes one item at a time (slow but predictable)
- `isSequential: false` โ†’ Executes up to `batchCount` items in parallel
- Maximum `batchCount` is **50** regardless of setting
- **Cannot use Set Variable activity** inside parallel ForEach (variable scope is pipeline-level)

### Set Variable Activity Limitations
โŒ **CANNOT** use `Set Variable` inside ForEach with `isSequential: false`
- Reason: Variables are pipeline-scoped, not ForEach-scoped
- Multiple parallel iterations would cause race conditions
- โœ… **Alternative**: Use `Append Variable` with array type, or use sequential execution

## ๐Ÿ“Š Linked Services Validation (Azure Blob, Azure SQL)

Detailed validation rules and templates for ADF Linked Services (Azure Blob Storage and Azure SQL Database) โ€” auth types (key, SAS, managed identity, AAD), network configuration, and connection-string patterns โ€” live in `references/linked-services.md`. Load that reference when authoring or validating a Linked Service JSON.

## ๐Ÿ” Data Flow Limitations

### General Limits
- **Column name length**: 128 characters maximum
- **Row size**: 1 MB maximum (some sinks like SQL have lower limits)
- **String column size**: Varies by sink (SQL: 8000 for varchar, 4000 for nvarchar)

### Transformation-Specific Limits
| Transformation | Limitation |
|----------------|------------|
| **Lookup** | Cache size limited by cluster memory |
| **Join** | Large joins may cause memory errors |
| **Pivot** | Maximum 10,000 unique values |
| **Window** | Requires partitioning for large datasets |

### Performance Considerations
- **Partitioning**: Always partition large datasets before transformations
- **Broadcast**: Use broadcast hint for small dimension tables
- **Sink optimization**: Enable table option "Recreate" instead of "Truncate" for better performance

## ๐Ÿ›ก๏ธ Validation Checklist for Pipeline Creation

### Before Creating Pipeline
- [ ] Verify activity nesting follows permitted combinations
- [ ] Check ForEach activities don't contain other ForEach/Until
- [ ] Verify If/Switch activities don't contain ForEach/Until/If/Switch
- [ ] Ensure Validation activities are at pipeline root level only
- [ ] Confirm total activities < 80 per pipeline
- [ ] Verify no Set Variable activities in parallel ForEach

### Linked Service Validation
- [ ] **Blob Storage**: If using managed identity/service principal, `accountKind` is set
- [ ] **SQL Database**: Authentication method matches security requirements
- [ ] **All services**: Secrets stored in Key Vault, not hardcoded
- [ ] **All services**: Firewall rules configured for integration runtime IPs
- [ ] **Network**: Private endpoints configured if using VNet integration

### Activity Configuration Validation
- [ ] **ForEach**: `batchCount` โ‰ค 50 if parallel execution
- [ ] **Lookup**: Query returns < 5000 rows and < 4 MB data
- [ ] **Copy**: DIU configured appropriately (2-256 for Azure IR)
- [ ] **Copy**: Staging enabled for large data movements
- [ ] **All activities**: Timeout values appropriate for expected execution time
- [ ] **All activities**: Retry logic configured for transient failures

### Data Flow Validation
- [ ] Column names โ‰ค 128 characters
- [ ] Source query doesn'

Related in General