Logical
Evaluates an expression and returns a specified value if the expression returns an error
IFERROR(<value>, <value_if_error>)
IFERROR Function in DAX - Comprehensive Guide with Contoso Data
Function Overview
IFERROR is a defensive DAX function that evaluates an expression and returns a specified alternative value if the expression produces an error. If the expression executes successfully without errors, IFERROR returns the result of the expression itself. This function is essential for creating robust, production-ready measures that won't break your reports when encountering problematic data or edge cases.
Applies to:
- ✅ Calculated columns
- ✅ Calculated tables
- ✅ Measures
- ✅ Visual calculations
Syntax
IFERROR(value, value_if_error)
Parameters
Parameter | Definition |
value | Any value or expression that you want to evaluate. This could be a calculation, lookup, division, or any DAX expression that might potentially produce an error. |
value_if_error | Any value or expression to return if the first parameter produces an error. This is your "fallback" or "safety net" value. |
Return Value
Returns a scalar value of the same data type as the value parameter:
- If
valueevaluates successfully → returns the result ofvalue - If
valueproduces an error → returnsvalue_if_error
Critical Requirement: Both value and value_if_error must return the same data type (both numbers, both text, etc.). You cannot return a number for success and text for error.
Why IFERROR Matters: Common Error Scenarios in Business Analytics
In real-world business intelligence, errors can occur in many situations:
- Division by zero: Calculating margins when cost is zero
- Lookup failures: Searching for values that don't exist in related tables
- Type mismatches: Attempting mathematical operations on incompatible data types
- Aggregate errors: Calculations on empty or filtered-out data sets
- Date calculation errors: Working with invalid or missing dates
Without IFERROR protection, a single error in one cell can:
- Break an entire visual or report page
- Display confusing error messages to business users
- Prevent dashboards from refreshing
- Undermine confidence in your analytics
IFERROR provides a safety net that keeps your reports running smoothly even when unexpected data issues arise.
Understanding the Relationship: IFERROR, IF, and ISERROR
The IFERROR function is actually a simplified combination of IF and ISERROR functions. Understanding this relationship helps you grasp how IFERROR works:
IFERROR(A, B)
Is equivalent to:
IF(ISERROR(A), B, A)
Breaking this down:
ISERROR(A)checks if expression A produces an error- If TRUE (there is an error), return B
- If FALSE (no error), return A
IFERROR simply packages this common pattern into a more concise, readable function.
Practical Example 1: Profit Margin Calculation with Contoso Data
Business Scenario
You are analyzing product profitability for Contoso. The finance team wants to see the profit margin percentage for each product, calculated as:
Profit Margin % = (Sales Amount - Total Cost) / Sales Amount × 100
However, some products in your database have zero sales (perhaps they're newly listed items, returned products, or discontinued items). When sales amount is zero, this creates a divide-by-zero error that breaks your report.
The Contoso Database Context
For this example, we're working with:
- FactSales table: Contains SalesAmount and TotalCost columns
- DimProduct table: Contains product information
- Some products have transactions, others don't
Step 1: Create Basic Sales and Cost Measures
First, let's create fundamental measures:
Total Sales = SUM(FactSales[SalesAmount])
Total Cost = SUM(FactSales[TotalCost])
Explanation: These measures aggregate sales revenue and product costs from the FactSales table. When filtered by product, they show that specific product's totals.
Step 2: Create Profit Margin WITHOUT Error Handling (The Problem)
Let's first see what happens WITHOUT IFERROR:
Profit Margin % (Unsafe) =
DIVIDE([Total Sales] - [Total Cost], [Total Sales]) * 100
What happens with this formula:
For Product: "Contoso 512MB MP3 Player E51 Silver"
- Total Sales = $5,635.16
- Total Cost = $2,704.08
- Calculation: ($5,635.16 - $2,704.08) / $5,635.16 × 100 = 52.01% ✅ Works fine
For Product: "Adventure Works 10W Laptop E1910 Black" (newly listed, no sales)
- Total Sales = $0 (or BLANK)
- Total Cost = $0 (or BLANK)
- Calculation: ($0 - $0) / $0 × 100 = #ERROR ❌ Division by zero!
This error can break your entire visual and create a poor user experience.
Step 3: Create Profit Margin WITH IFERROR Protection (The Solution)
Now let's implement proper error handling:
Profit Margin % =
IFERROR(
DIVIDE([Total Sales] - [Total Cost], [Total Sales]) * 100,
0
)
Detailed Step-by-Step Breakdown:
1. IFERROR( ... ) - The protective wrapper function
- First parameter: The calculation we want to attempt
- Second parameter: What to return if there's an error
2. DIVIDE([Total Sales] - [Total Cost], [Total Sales]) * 100 - The value parameter
- This is the actual profit margin calculation
- Numerator:
[Total Sales] - [Total Cost]= Profit amount - Denominator:
[Total Sales]= Revenue base - Multiplied by 100 to convert to percentage
- This might produce an error if Total Sales is zero
3. 0 - The value_if_error parameter
- Returns 0% if the calculation fails
- Business logic: "If we can't calculate margin, show 0%"
- Alternative options: BLANK(), "N/A", -1 (depending on business requirements)
How It Works: Execution Flow for Different Products
Scenario A: Product with Normal Sales
Product: "Contoso 512MB MP3 Player E51 Silver"
- Total Sales = $5,635.16
- Total Cost = $2,704.08
- Calculation attempts: ($5,635.16 - $2,704.08) / $5,635.16 × 100
- Result: 52.01 (no error)
- IFERROR sees no error
- Returns: 52.01% ✅
Scenario B: Product with Zero Sales
Product: "Adventure Works 10W Laptop E1910 Black"
- Total Sales = $0
- Total Cost = $0
- Calculation attempts: ($0 - $0) / $0 × 100
- Result: ERROR (division by zero)
- IFERROR catches the error
- Returns: 0% ✅
Scenario C: Product with BLANK Sales
Product: "Fabrikam Laptop14.1 M1402 Black" (listed but never sold)
- Total Sales = BLANK
- Total Cost = BLANK
- Calculation attempts: (BLANK - BLANK) / BLANK × 100
- Result: ERROR (division by blank)
- IFERROR catches the error
- Returns: 0% ✅
Example Output Table with Contoso Data
Product Name | Total Sales | Total Cost | Profit Margin % |
Contoso 512MB MP3 Player E51 Silver | $5,635.16 | $2,704.08 | 52.01% |
Contoso 2G MP3 Player E51 Silver | $3,318.33 | $1,593.60 | 51.98% |
Fabrikam Laptop14.1 M1402 Grey | $8,277.33 | $5,530.89 | 33.18% |
Adventure Works 10W Laptop E1910 Black | $0.00 | $0.00 | 0.00% |
Wide World Importers 320W E320 Red | - | - | 0.00% |
Grand Total | $29,052,297.60 | $18,393,382.78 | 36.68% |
Business Interpretation
The IFERROR-protected formula allows the report to display cleanly:
- Products with sales show their actual profit margins (ranging from 33% to 52%)
- Products without sales show 0%, which is more meaningful than an error
- The report remains functional and professional
- Users can make decisions based on complete data
Practical Example 2: Average Sales Per Transaction with Error Handling
Business Scenario
The sales team wants to analyze the average transaction size for each sales channel. Some newer sales channels might not have any completed transactions yet, which would cause a divide-by-zero error when calculating average sales.
Without IFERROR (The Problem)
Average Transaction Size (Unsafe) =
DIVIDE([Total Sales], COUNTROWS(FactSales))
Issues:
- If a sales channel has no transactions, COUNTROWS returns 0
- Division by zero creates an error
- The entire report visual fails
With IFERROR (The Solution)
Average Transaction Size =
IFERROR(
DIVIDE([Total Sales], COUNTROWS(FactSales)),
BLANK()
)
Why use BLANK() instead of 0?
In this scenario, returning BLANK() is more appropriate than 0 because:
- $0 average suggests transactions occurred but had no value
- BLANK() correctly indicates "no data available"
- BLANK() will hide the row in many visuals, reducing clutter
- Business users understand "no data" vs. "zero value"
Example Output with Different Sales Channels
Sales Channel | Total Sales | Transaction Count | Average Transaction Size |
Online Store | $12,427,851.32 | 54,628 | $227.51 |
Reseller | $16,624,446.28 | 21,394 | $776.95 |
Catalog | $0.00 | 0 | - |
Grand Total | $29,052,297.60 | 76,022 | $382.12 |
Notice how "Catalog" shows a dash (-) instead of an error or $0, which accurately represents "no transactions to average."
Practical Example 3: Product Lookup with Error Protection
Business Scenario
You need to create a calculated column that looks up the product category from the DimProduct table. However, some sales records might have invalid or missing ProductKey values that don't match any product in the DimProduct table, causing RELATED function errors.
Without IFERROR (The Problem)
Product Category (Unsafe) =
RELATED(DimProduct[ProductCategoryName])
Issues:
- If ProductKey doesn't exist in DimProduct, RELATED returns an error
- The calculated column fails to create
- Data model won't refresh
With IFERROR (The Solution)
Product Category =
IFERROR(
RELATED(DimProduct[ProductCategoryName]),
"Unknown Category"
)
Detailed Explanation:
1. RELATED(DimProduct[ProductCategoryName]) - The lookup expression
- Attempts to retrieve the category name from the related DimProduct table
- Follows the relationship between FactSales[ProductKey] and DimProduct[ProductKey]
- If the ProductKey doesn't exist in DimProduct, this produces an error
2. "Unknown Category" - The fallback value
- Returns this text if the lookup fails
- Allows you to identify and investigate data quality issues
- Keeps the model functional even with orphaned records
Example Output in FactSales Table
SalesKey | ProductKey | SalesAmount | Product Category |
1 | 2148 | $2,147.95 | Computers |
2 | 1547 | $699.99 | Audio |
3 | 9999 | $449.99 | Unknown Category |
4 | 3312 | $1,299.00 | TV and Video |
Notice row 3: ProductKey 9999 doesn't exist in DimProduct, but instead of breaking the model, it returns "Unknown Category" allowing you to identify and fix data quality issues.
Comparison: IFERROR vs. ISBLANK vs. DIVIDE
Understanding when to use each function is crucial for writing clean, efficient DAX:
IFERROR
Use when: You need to catch ANY type of error (division, lookup, type mismatch, etc.)
IFERROR([Risky Calculation], [Fallback Value])
Catches:
- Division by zero
- Type conversion errors
- Lookup failures
- Aggregate errors
- Any calculation error
ISBLANK
Use when: You specifically need to detect blank/missing values
IF(ISBLANK([Value]), [Alternative], [Normal Calculation])
Catches:
- NULL values
- Empty cells
- Results that return BLANK()
Does NOT catch:
- Division by zero
- Other calculation errors
- Zero values (0 is not blank)
DIVIDE
Use when: You only need to handle division operations safely
DIVIDE([Numerator], [Denominator], [Alternative])
Features:
- Built-in divide-by-zero protection
- Cleaner syntax than IFERROR for simple division
- Returns alternative value if denominator is zero or blank
Decision Matrix
Scenario | Best Choice | Why |
Simple division only | DIVIDE | Built-in, optimized, clean |
Division + other logic | IFERROR | Comprehensive error handling |
Checking for missing data | ISBLANK | Explicit intent, readable |
Complex calculations prone to multiple error types | IFERROR | Catches all errors |
Lookup operations (RELATED, LOOKUPVALUE) | IFERROR | Protects against missing keys |
Example: Combining IFERROR with Multiple Error-Prone Operations
Complex Business Scenario
Calculate a "Customer Lifetime Value Score" that involves:
- Division (total sales / transaction count)
- Lookup (customer tier from another table)
- Date calculation (days since first purchase)
Why IFERROR is essential here:
- Division could fail (transaction count = 0)
- RELATED could fail (orphaned customer records)
- DATEDIFF could fail (invalid dates)
- Any single failure would break the entire calculation
IFERROR wraps the entire complex calculation, ensuring a safe fallback value (0) if any component fails.
Important Remarks and Best Practices
1. Empty Cell Handling
If value or value_if_error is an empty cell, IFERROR treats it as an empty string value (""). This is important for calculated columns working with text data.
2. Data Type Consistency
Critical Rule: Both parameters must return the same data type.
Valid Examples:
IFERROR([Numeric Calculation], 0) // Both return numbers
IFERROR([Text Lookup], "Not Found") // Both return text
IFERROR([Date Calculation], BLANK()) // Compatible types
Invalid Examples:
IFERROR([Numeric Calculation], "N/A") // ❌ Number vs. Text
IFERROR([Date Calculation], 0) // ❌ Date vs. Number
3. Performance Considerations
IFERROR adds a small performance overhead because it must:
- Execute the calculation
- Check for errors
- Potentially execute the fallback
For large datasets with millions of rows, consider:
- Using DIVIDE instead of IFERROR for simple divisions (it's optimized)
- Fixing data quality issues at the source rather than masking them
- Using ISBLANK when you're only checking for blank values
4. DirectQuery Limitations
IFERROR is not supported for:
- Calculated columns in DirectQuery mode
- Row-level security (RLS) rules
If you're using DirectQuery, you'll need alternative approaches like DIVIDE or addressing errors in the source database.
5. Best Practices from Microsoft
According to Microsoft's DAX guidelines:
- Don't overuse IFERROR - It can mask underlying data quality issues
- Be specific - Use DIVIDE for division, ISBLANK for blanks when possible
- Document your fallback values - Make it clear why you chose 0 vs. BLANK vs. another value
- Monitor errors - Use IFERROR as a safety net, not a permanent solution to data problems
6. Debugging Tip
When developing measures, temporarily remove IFERROR to see what errors occur:
// Development version - see the actual errors
Profit Margin % (Debug) =
DIVIDE([Total Sales] - [Total Cost], [Total Sales]) * 100
// Production version - handle errors gracefully
Profit Margin % =
IFERROR(
DIVIDE([Total Sales] - [Total Cost], [Total Sales]) * 100,
0
)
This helps you identify and fix root causes rather than just hiding errors.
Choosing the Right Fallback Value
The value_if_error parameter deserves careful consideration:
Fallback Value | When to Use | Example Scenario |
0 | When zero is a meaningful "no value" indicator | Profit margin for products with no sales |
BLANK() | When you want to hide rows or indicate "no data" | Average transaction size for inactive channels |
-1 | When you want errors to be obvious for investigation | Data quality audits |
"N/A" or "Error" | For text columns where you want explicit error indication | Category lookups |
Previous value | For running calculations where errors should use last known good value | Time series analysis |
Summary
The IFERROR function is your safety net for creating production-ready, error-resistant DAX calculations. When working with Contoso data (or any real-world dataset), you'll inevitably encounter:
- Division by zero situations
- Missing lookup values
- Invalid data that causes calculation errors
- Edge cases that weren't considered during development
IFERROR allows you to: ✅ Build robust measures that don't break reports ✅ Provide meaningful fallback values for error situations ✅ Create professional, user-friendly analytics ✅ Maintain business continuity even with data quality issues
Key Takeaway: Use IFERROR as a defensive programming tool to protect against errors, but always investigate and fix the underlying data quality issues when possible. IFERROR should be your safety net, not a permanent band-aid for bad data.