How This Mess Started
Last month we wrote an automation script to batch-configure new HPE Gen11 servers via Redfish API. Two boxes, both Gen11 — one running iLO 6 v1.53, the other v1.66. Identical hardware configs.
The script ran fine on the older firmware. The newer one? Constant HTTP 400 Bad Request. I spent hours digging through Reddit threads — that “Redfish api drives return error” post got bookmarked real quick.
Turned out it wasn’t our script. It was a combination of Redfish spec ambiguities and vendor implementation quirks. Here’s everything we learned the hard way.
Symptom Breakdown: You’ll Hit These Too
Case 1: PATCH password change returns HTTP 400
curl -X PATCH \
-H "Content-Type: application/json" \
-H "X-Auth-Token: $TOKEN" \
-d '{"Password": "NewP@ss123"}' \
https://bmc-ip/redfish/v1/AccountService/Accounts/1
Response:
{
"error": {
"code": "Base.1.13.GeneralError",
"message": "A general error has occurred.",
"@Message.ExtendedInfo": [
{
"MessageId": "Base.1.13.PropertyValueNotInList",
"Message": "The value 'NewP@ss123' for the property 'Password' is not in the list of acceptable values.",
"Severity": "Warning"
}
]
}
}
Case 2: GET network adapter info returns HTTP 500
curl -s -H "X-Auth-Token: $TOKEN" \
https://bmc-ip/redfish/v1/Chassis/1/NetworkAdapters
Returns 500 Internal Server Error with zero ExtendedInfo. The most infuriating kind — the server just blows up silently.
Case 3: Setting one-time boot to PXE returns HTTP 400
This one’s endemic to HPE ProLiant DL380 Gen10 with iLO 5. Someone on Reddit reported redfish_command failing on PATCH to the Boot resource with HTTP Error 400. I’ve reproduced it on three separate boxes.
Root Cause Analysis: Who’s Really at Fault
Let’s break each case down.
1. Password Policy Collision (Case 1)
Here’s the kicker: the Redfish spec doesn’t define password validation rules for the Password property. But iLO and iDRAC each have their own complexity requirements. You send a perfectly valid string by spec standards, and the BMC’s password policy validator rejects it.
What makes it worse is the error message. PropertyValueNotInList means “the value isn’t in the list of acceptable values.” But you’re passing a string, not an enum. The vendor literally used the wrong error type — should’ve been PropertyValueFormatError or PropertyValueModified.
2. Firmware Bug Causing Internal Server Error (Case 2)
HTTP 500 in Redfish almost always means the BMC crashed while processing your request. We captured the traffic and found that when GETting /Chassis/1/NetworkAdapters, the iDRAC’s JSON serializer hit a null health status field on one of the NICs. No null check. Straight-up NullPointerException.
This is a firmware quality issue. The DMTF spec explicitly says servers should return 4xx with ExtendedInfo, not 500. But vendors gonna vendor.
3. Overly Strict Boot Resource Validation (Case 3)
When setting the one-time boot override, your JSON body needs BootSourceOverrideTarget and BootSourceOverrideEnabled. The problem? Some iLO firmware versions require both properties to be present and processed in a specific order — BootSourceOverrideEnabled first.
Send only BootSourceOverrideTarget: "Pxe" without BootSourceOverrideEnabled? 400. Send them in the wrong order? Also 400.
Fix Steps: From Trench to Triumph
Step 1: Enable Redfish Debug Logging
# On iDRAC
racadm set iDRAC.Redfish.DebugLevel 2
racadm set iDRAC.Redfish.LogToFile Enabled
# On iLO via SSH
ssh Administrator@bmc-ip
> set /map1/dump1/flag OemRHD_EnableDebugLogs 1
> set /map1/dump1/flag OemRHD_EnableVerboseLogging 1
Reproduce the issue, then pull the BMC logs. This is how we found the NPE stack trace that confirmed the firmware bug.
Step 2: Fix Password Change Requests
Don’t PATCH the Password property directly. Use the ChangePassword action instead — it’s the spec-compliant way.
# Correct approach: POST to ChangePassword action
curl -X POST \
-H "Content-Type: application/json" \
-H "X-Auth-Token: $TOKEN" \
-d '{
"OldPassword": "oldPassword12",
"NewPassword": "NewP@ss123!"
}' \
https://bmc-ip/redfish/v1/AccountService/Actions/AccountService.ChangePassword
If your BMC doesn’t support the ChangePassword action (some older firmwares don’t), GET the password policy first:
# Fetch password policy
curl -s -H "X-Auth-Token: $TOKEN" \
https://bmc-ip/redfish/v1/AccountService | jq '.Oem'
# Check MinPasswordLength, PasswordPattern, etc.
# Generate a password that complies
Step 3: Work Around Internal Server Error (Case 2)
For firmware bugs causing 500s, downgrade your access path:
# Don't hit /Chassis/1/NetworkAdapters directly
# Use /Systems/1/NetworkInterfaces instead
curl -s -H "X-Auth-Token: $TOKEN" \
https://bmc-ip/redfish/v1/Systems/1/NetworkInterfaces | jq '.Members[] | .@odata.id'
Or use OData query parameters to skip problematic properties:
curl -s -H "X-Auth-Token: $TOKEN" \
"https://bmc-ip/redfish/v1/Chassis/1/NetworkAdapters?\$select=Id,Name,Status"
We filed a ticket with the vendor — two weeks later a new firmware fixed it. Until then, this workaround kept us operational.
Step 4: Fix One-Time Boot Override (Case 3)
# Correct: send both properties, BootSourceOverrideEnabled first
curl -X PATCH \
-H "Content-Type: application/json" \
-H "X-Auth-Token: $TOKEN" \
-d '{
"BootSourceOverrideEnabled": "Once",
"BootSourceOverrideTarget": "Pxe"
}' \
https://bmc-ip/redfish/v1/Systems/1/BootOptions/1
HPE iLO cares about property order. Dell iDRAC doesn’t. One more vendor-specific quirk to track.
Step 5: Implement Robust Error Handling
def redfish_patch(url, payload, token, retries=3):
for attempt in range(retries):
resp = requests.patch(url, json=payload, headers={"X-Auth-Token": token})
if resp.status_code == 200:
return resp.json()
elif resp.status_code == 400:
msgs = resp.json().get("error", {}).get("@Message.ExtendedInfo", [])
for msg in msgs:
mid = msg.get("MessageId", "")
if "PropertyValueNotInList" in mid:
policy = get_password_policy(url, token)
payload["Password"] = generate_valid_password(policy)
elif "ActionNotSupported" in mid:
return fallback_patch(url, payload, token)
elif resp.status_code == 500:
time.sleep(5)
url = find_alternative_endpoint(url)
raise Exception("Redfish API retries exhausted")
Vendor Redfish Implementation Comparison
| Feature | HPE iLO 6 | Dell iDRAC 9 | Lenovo XClarity |
|---|---|---|---|
| PATCH password support | ✅ ChangePassword action | ✅ Direct PATCH | ✅ ChangePassword action |
| Password policy exposure | Via Oem.Hpe.PasswordRules | Via Oem.Dell.DellPasswordService | Via Oem.Lenovo.PasswordPolicy |
| Boot property order-sensitive | ✅ Yes | ❌ No | ❌ No |
| 500 error frequency | Low (FW 1.60+) | Medium (specific endpoints) | Low |
| ExtendedInfo completeness | High | Medium (sometimes missing) | High |
| Auth methods | Session + Token | Session + Token + Basic | Session + Token |
FAQ
What’s an API error code?
HTTP status code. 200 = success, 4xx = client problem (bad data), 5xx = server problem (BMC crashed). Redfish extends this with @Message.ExtendedInfo — way more useful than bare HTTP codes.
What is the Redfish API?
DMTF’s standard for hardware management. RESTful HTTP + JSON, replacing ancient IPMI. Covers everything from single servers to rack-level management. Think of it as your BMC’s REST API.
When would I get a 500 Internal Server Error?
When the BMC firmware crashes processing your request. Common causes: null pointer exceptions during JSON serialization, unhandled state machine transitions, or memory corruption. Our rule of thumb: update to latest firmware — fixes 80% of 500 errors.
How do I enable the Redfish service?
- iDRAC: Web UI →
Overview > iDRAC Settings > Network > Services→ enable Redfish. - iLO: Web UI →
Administration > Access Settings > Services→ enable Redfish REST API. - CLI:
racadm set iDRAC.Redfish.Enable 1(Dell) or SSH into iLO →set /map1/config/RedfishEnabled 1(HPE).
Final Thoughts
Redfish is a solid protocol. But vendor implementations are all over the map. Every single issue we hit boiled down to firmware quality and spec compliance gaps.
If you’re automating with Redfish, here’s my advice:
- Update your BMC firmware first. The 500 error we hit? Fixed in the next release.
- Don’t trust vendor docs. Packet capture is your friend.
- Build vendor-specific adapters. A universal Redfish client? Doesn’t exist in practice.
That Reddit thread about “Redfish api drives return error”? The OP fixed it by upgrading firmware. So yeah — update your damn firmware before you do anything else.