Ops Notes

Redfish API Configuration Guide 2026: From Zero to Production-Ready

Infrastructure Visualization

The Official Docs Are Garbage

I’ve read the DMTF Redfish specification cover to cover. Twice. It reads like a legal contract—technically correct but absolutely useless when you’re trying to get something done in production.

Last week our team migrated a 48-node cluster from IPMI to Redfish. It was a dumpster fire. This article is what I learned from that bloodbath, updated for 2026 best practices.

What Even Is Redfish?

Redfish is the RESTful API standard for modern server management. It replaces the ancient IPMI protocol with HTTPS+JSON. No more binary protocols, no more ipmitool hacks.

DMTF calls it “a standard designed to deliver simple and secure management for converged, hybrid IT and the Software Defined Data Center.” In plain English: you can control every aspect of your servers with simple HTTP requests—BIOS settings, firmware updates, power management, sensor monitoring, you name it.

The 2026 Redfish Landscape

Vendor Support Matrix

VendorRedfish VersionStability ScorePain Points
Dell iDRAC 9+2024.3⭐⭐⭐⭐Some endpoints return non-standard JSON
HPE iLO 6+2024.2⭐⭐⭐⭐⭐Best docs, but licenses are expensive
Supermicro BMC2024.1⭐⭐⭐Random 500 errors, need retry logic
Lenovo XClarity2024.3⭐⭐⭐⭐Requires BMC restart after config changes
Inspur2023.x⭐⭐Worst compatibility, avoid if possible

Supermicro updated their Redfish API in 2026, but honestly some endpoints still randomly return 500 errors. Our fix: three retries with exponential backoff. Solved 95% of the issues.

Step 1: Initial Configuration

1. Enable the Redfish Service

The process varies by vendor, but it’s always in the BMC web interface. For Dell iDRAC9:

  1. Log into iDRAC web UI
  2. Go to ConfigurationNetwork Settings
  3. Ensure IPMI over LAN is enabled (Redfish depends on it)
  4. Enable Web Server (HTTPS port defaults to 443)

Pro tip: Some vendors ship with Redfish in read-only mode by default. Check SettingsRedfish and enable Write Mode, otherwise you can only GET, not PATCH.

2. Create Dedicated API Users

Never use root/admin accounts for automation scripts. That’s just asking for trouble.

# Create a read-only monitoring user via Redfish API
curl -k -X POST https://<BMC_IP>/redfish/v1/AccountService/Accounts \
  -H "Content-Type: application/json" \
  -u "admin:your_admin_password" \
  -d '{
    "UserName": "monitor_user",
    "Password": "SecurePass123!",
    "RoleId": "ReadOnly",
    "Enabled": true
  }'

# Create an operator user for actual operations
curl -k -X POST https://<BMC_IP>/redfish/v1/AccountService/Accounts \
  -H "Content-Type: application/json" \
  -u "admin:your_admin_password" \
  -d '{
    "UserName": "ops_user",
    "Password": "AnotherSecurePass456!",
    "RoleId": "Operator",
    "Enabled": true
  }'

Step 2: Core API Endpoints in Practice

Getting System Info

This is the first API you should test:

# Get basic system information
curl -sk https://<BMC_IP>/redfish/v1/Systems/System.Embedded.1 \
  -u "ops_user:password" | jq .

# Extract key fields
curl -sk https://<BMC_IP>/redfish/v1/Systems/System.Embedded.1 \
  -u "ops_user:password" | jq '{Model, Manufacturer, BiosVersion, MemorySummary, ProcessorSummary}'

Heads up: System IDs aren’t standard. Dell uses System.Embedded.1, HPE uses 1, Supermicro uses 1U or 1. Don’t hardcode—first GET /redfish/v1/Systems/ and see what comes back.

Power Management

I use this daily. Remote restart a hung server in under a minute.

# Graceful shutdown
curl -sk -X POST https://<BMC_IP>/redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset \
  -H "Content-Type: application/json" \
  -u "ops_user:password" \
  -d '{"ResetType": "GracefulShutdown"}'

# Force restart (for frozen systems)
curl -sk -X POST https://<BMC_IP>/redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset \
  -H "Content-Type: application/json" \
  -u "ops_user:password" \
  -d '{"ResetType": "ForceRestart"}'

ResetType Reference:

TypeBehaviorWhen to Use
OnPower onServer is off
GracefulShutdownClean shutdownScheduled maintenance
ForceRestartHard rebootSystem unresponsive
ForceOffEmergency power offLast resort
PowerCycleOff then onDeep reset

BIOS Configuration Management

This feature has saved my ass more times than I can count. Configuring BIOS on 48 servers manually? No thanks.

# View current BIOS config
curl -sk https://<BMC_IP>/redfish/v1/Systems/System.Embedded.1/Bios \
  -u "ops_user:password" | jq '.Attributes | {BootMode, ProcTurboMode, ProcVirtualization}'

# Modify BIOS settings
curl -sk -X PATCH https://<BMC_IP>/redfish/v1/Systems/System.Embedded.1/Bios/Settings \
  -H "Content-Type: application/json" \
  -u "ops_user:password" \
  -d '{
    "Attributes": {
      "BootMode": "Uefi",
      "ProcTurboMode": "Enabled",
      "ProcVirtualization": "Enabled"
    }
  }'

# Verify pending settings
curl -sk https://<BMC_IP>/redfish/v1/Systems/System.Embedded.1/Bios/Settings \
  -u "ops_user:password" | jq '.Attributes'

Pain point: BIOS attribute names are completely different between vendors. Dell calls it BootMode, HPE might call it BootMode too but the values differ. Always GET the full config first, search for what you need, then PATCH.

Firmware Updates

This is the riskiest operation. One wrong move and you’ve got a brick.

# 1. Upload firmware to BMC
curl -sk -X POST https://<BMC_IP>/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate \
  -H "Content-Type: application/json" \
  -u "ops_user:password" \
  -d '{
    "ImageURI": "https://your-ftp-server/firmware/BIOS_XXXX.bin",
    "@Redfish.OperationApplyTime": "OnReset"
  }'

# 2. Check task status
curl -sk https://<BMC_IP>/redfish/v1/TaskService/Tasks/<TaskID> \
  -u "ops_user:password" | jq '.TaskState, .PercentComplete'

My hard rules for firmware updates:

  • Never during business hours
  • Always test on one machine first, wait 24 hours
  • Have a rollback plan (some vendors support it, some don’t)
  • Make damn sure your UPS is working

Step 3: Automation Scripts

Python Implementation

This is what we actually run in production:

import requests
import json
import time
from requests.auth import HTTPBasicAuth
from urllib3.exceptions import InsecureRequestWarning

# Don't disable SSL in production! This is for testing.
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

class RedfishManager:
    def __init__(self, bmc_ip, username, password):
        self.base_url = f"https://{bmc_ip}/redfish/v1"
        self.auth = HTTPBasicAuth(username, password)
        self.session = requests.Session()
        self.session.auth = self.auth
        self.session.verify = False
        # Prevent hanging on unresponsive BMC
        self.session.timeout = (10, 30)

    def get_system_info(self, system_id="System.Embedded.1"):
        """Get system information"""
        url = f"{self.base_url}/Systems/{system_id}"
        resp = self.session.get(url)
        resp.raise_for_status()
        return resp.json()

    def power_action(self, system_id, action):
        """Execute power operation"""
        url = f"{self.base_url}/Systems/{system_id}/Actions/ComputerSystem.Reset"
        payload = {"ResetType": action}
        resp = self.session.post(url, json=payload)
        resp.raise_for_status()
        return resp.status_code

    def set_bios_attribute(self, system_id, attributes):
        """Set BIOS attributes"""
        url = f"{self.base_url}/Systems/{system_id}/Bios/Settings"
        payload = {"Attributes": attributes}
        resp = self.session.patch(url, json=payload)
        resp.raise_for_status()
        return resp.status_code

    def get_thermal_info(self, chassis_id="Chassis.System.Embedded.1"):
        """Get temperature sensor data"""
        url = f"{self.base_url}/Chassis/{chassis_id}/Thermal"
        resp = self.session.get(url)
        resp.raise_for_status()
        data = resp.json()
        sensors = []
        for temp in data.get("Temperatures", []):
            sensors.append({
                "name": temp["Name"],
                "reading": temp["ReadingCelsius"],
                "status": temp["Status"]["Health"]
            })
        return sensors

    def update_firmware(self, image_uri):
        """Trigger firmware update"""
        url = f"{self.base_url}/UpdateService/Actions/UpdateService.SimpleUpdate"
        payload = {
            "ImageURI": image_uri,
            "@Redfish.OperationApplyTime": "OnReset"
        }
        resp = self.session.post(url, json=payload)
        resp.raise_for_status()
        task_url = resp.headers.get("Location")
        return task_url

# Usage
if __name__ == "__main__":
    mgr = RedfishManager("192.168.1.100", "ops_user", "SecurePass456!")
    
    info = mgr.get_system_info()
    print(f"Model: {info.get('Model')}")
    print(f"BIOS Version: {info.get('BiosVersion')}")
    
    sensors = mgr.get_thermal_info()
    for s in sensors:
        print(f"{s['name']}: {s['reading']}°C [{s['status']}]")
    
    # Uncomment with caution!
    # mgr.power_action("System.Embedded.1", "GracefulShutdown")
    # time.sleep(60)
    # mgr.power_action("System.Embedded.1", "On")

Step 4: Production Best Practices

Security Configuration

This is what most people get wrong in 2026. I’ve seen BMC ports exposed directly to the internet—it’s terrifying.

SettingRecommendationWhy
HTTPSForce on, disable HTTPPasswords in plaintext = bad
TLS VersionMinimum TLS 1.2TLS 1.0/1.1 are deprecated
Password Policy12+ chars with special charsBrute force protection
Access ControlIP whitelistManagement network only
Session Timeout15 minutesReduce hijacking risk
Audit LoggingEnableTrack who did what

Monitoring Setup

We scrape Redfish metrics directly into Prometheus:

# prometheus.yml redfish scrape config
scrape_configs:
  - job_name: 'redfish_hardware'
    scrape_interval: 60s
    metrics_path: '/redfish/v1/Chassis/Chassis.System.Embedded.1/Thermal'
    scheme: https
    basic_auth:
      username: 'monitor_user'
      password: 'SecurePass123!'
    tls_config:
      insecure_skip_verify: true  # Use valid certs in production
    relabel_configs:
      - source_labels: [__address__]
        target_label: instance

Common Failure Modes

Issue 1: Random 500 Errors

Usually a BMC firmware bug. We hit this constantly on Supermicro gear.

Fix:

import time
from tenacity import retry, stop_after_attempt, wait_exponential

@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
def safe_redfish_get(url, auth):
    resp = requests.get(url, auth=auth, verify=False, timeout=30)
    resp.raise_for_status()
    return resp.json()

Issue 2: BIOS Changes Don’t Apply

Some vendors require a reboot for BIOS settings to take effect. And you need to wait for the BMC to reload after reboot.

Correct workflow:

  1. PATCH BIOS/Settings
  2. Reboot server
  3. Wait 60 seconds
  4. GET BIOS to verify

Issue 3: Session Expiry

Redfish sessions expire after 30 minutes by default. Long-running scripts need session management.

# Create a session
session_resp = requests.post(
    f"{base_url}/SessionService/Sessions",
    json={"UserName": username, "Password": password},
    verify=False
)
token = session_resp.headers["X-Auth-Token"]

# Use token for subsequent requests
headers = {"X-Auth-Token": token}
resp = requests.get(f"{base_url}/Systems", headers=headers, verify=False)

Redfish in 2026 is way more mature than it was three years ago. Almost every major server vendor supports it natively—no extra plugins needed.

But the pain points remain:

  • Standardization is a lie: DMTF defines the standard, but every vendor implements it differently. Same endpoint, different JSON structure
  • Performance sucks on cheap hardware: Some low-end BMCs take 5 seconds to respond to a simple GET
  • Documentation quality varies wildly: Dell’s is decent, some vendors’ docs are completely unusable

FAQ

Q: What’s the difference between Redfish and IPMI?

A: IPMI uses binary protocols and requires specialized tools like ipmitool. Redfish uses HTTPS+JSON—you can use curl. Redfish is more modern with richer management features, but IPMI can be faster for simple operations.

Q: How do I check if my server supports Redfish?

A: Hit https://<BMC_IP>/redfish/v1/. If you get JSON back, you’re good. If not, update your BMC firmware.

Q: Is Redfish secure?

A: It can be. HTTPS encryption, RBAC access control, audit logging—it’s all there. But only if you don’t expose your BMC to the public internet. Please don’t do that.

Q: What tools do I need?

A: Minimum: curl + jq. For automation: Python with requests library, or PowerShell. No special clients required.

Q: How do I manage multiple servers at scale?

A: Write a script and loop through them. Ansible has a redfish_config module. Or roll your own Python script with async libraries for better performance.

Final Thoughts

Redfish is the future of server management, and in 2026 it’s the standard. Migrating from IPMI will hurt, but once it’s running, the efficiency gains are massive.

Three rules to live by:

  1. Security first: Never expose BMC to the internet
  2. Test everything: Validate every operation in staging first
  3. Document your pain: Every bug you hit today is a lesson for tomorrow

And seriously, don’t trust vendor documentation. Test everything yourself. When you hit a wall, come back to this guide—it’ll save you at least half a day.