---
name: openflow-ops-bulletins
description: Investigate and manage NiFi bulletins. Use when get_status shows bulletin_errors or bulletin_warnings > 0, or to clear bulletins between test runs.
---

# Bulletin Operations

This reference covers investigating and managing NiFi bulletins. Bulletins are explicit warnings and errors generated by NiFi components when something goes wrong (e.g., connection failures, configuration errors, processing exceptions).

**Note:** Clearing bulletins (NiFi 2.7.0+ / Openflow Runtime 2025.12+) modifies state. Reading bulletins is a safe, read-only operation.

## Scope

This reference covers:
- Retrieving bulletins for a process group or specific components
- Filtering bulletins by source name or message content
- Clearing bulletins between test runs (NiFi 2.7.0+ / Openflow Runtime 2025.12+)
- Interpreting bulletin messages for troubleshooting

This reference does NOT cover:
- Overall flow health monitoring (see `references/ops-flow-lifecycle.md` for `get_status`)
- Runtime pod or platform issues (see `references/platform-diagnostics.md`)
- Backpressure, queue depth, or thread utilization (use `get_status` metrics)

**Important:** Bulletins are ONE component of flow health. A flow with zero bulletins can still be unhealthy (e.g., backpressure, queued flowfiles not moving, stuck threads). Always start with `get_status` for comprehensive health metrics; use this reference when `bulletin_errors` or `bulletin_warnings` > 0.

## Key Concepts

| Term | Meaning |
|------|---------|
| **Bulletin** | An explicit warning or error message generated by a NiFi component |
| **Bulletin Board** | Centralized view of all bulletins across the flow |
| **Source Type** | The component type: PROCESSOR, CONTROLLER_SERVICE, INPUT_PORT, etc. |
| **Retention** | Bulletins expire after 5 minutes by default |

## Prerequisites

- nipyapi CLI installed and profile configured (see `references/setup-main.md`)
- Process group ID from `get_status` or `list_flows`
- For clearing: NiFi 2.7.0+ or Openflow Runtime 2025.12+

## CLI Commands Reference

| Command | Purpose |
|---------|---------|
| `nipyapi bulletins get_bulletin_board` | Get bulletins with optional filtering |
| `nipyapi bulletins clear_all_bulletins` | Clear all bulletins from a PG (2.7.0+ / 2025.12+) |

---

## 1. Get Bulletins for Process Group

When `get_status` shows `bulletin_errors` or `bulletin_warnings` > 0, get the actual messages:

```bash
nipyapi --profile <profile> bulletins get_bulletin_board --pg_id "<pg-id>"
```

### Bulletin Fields

| Field | Description |
|-------|-------------|
| `level` | Severity: ERROR, WARNING, or INFO |
| `source_name` | Name of the component that generated it |
| `source_type` | Type: PROCESSOR, CONTROLLER_SERVICE, etc. |
| `message` | Human-readable error description |
| `timestamp` | When the bulletin was generated |
| `stack_trace` | Java stack trace for exceptions (2.7.0+ / 2025.12+) |

### Python Example

```python
import nipyapi
nipyapi.profiles.switch('<profile>')

pg_id = "<pg-id>"
bulletins = nipyapi.bulletins.get_bulletin_board(pg_id=pg_id)

for b in bulletins:
    print(f"[{b.level}] {b.source_name} ({b.source_type})")
    print(f"  {b.message}")
    if b.stack_trace:
        print(f"  Stack trace available")
```

---

## 2. Filter Bulletins

### Filter by Source Name

Find bulletins from a specific processor or controller service:

```bash
nipyapi --profile <profile> bulletins get_bulletin_board \
  --pg_id "<pg-id>" \
  --source_name ".*MyProcessor.*"
```

The `source_name` parameter accepts regex patterns.

### Filter by Message

Search for specific error patterns:

```bash
nipyapi --profile <profile> bulletins get_bulletin_board \
  --pg_id "<pg-id>" \
  --message ".*connection refused.*"
```

Useful patterns:
- `.*timeout.*` - Connection or processing timeouts
- `.*authentication.*` - Auth failures
- `.*certificate.*` - TLS/SSL issues
- `.*null.*` - Null pointer or missing data

---

## 3. Clear All Bulletins (NiFi 2.7.0+ / Openflow 2025.12+)

Clear bulletins to establish a clean baseline before or after test runs:

```bash
nipyapi --profile <profile> bulletins clear_all_bulletins --pg_id "<pg-id>"
```

Returns the number of bulletins cleared.

### What Gets Cleared

| Component Type | Cleared |
|----------------|---------|
| Processors | Yes |
| Controller Services | Yes |
| Input/Output Ports | Yes |
| Funnels | Yes |
| Remote Process Groups | Yes |
| Flow Controller (system) | No - expires automatically |

### Python Example

```python
import nipyapi
nipyapi.profiles.switch('<profile>')

cleared = nipyapi.bulletins.clear_all_bulletins(pg_id="<pg-id>")
print(f"Cleared {cleared} bulletins")
```

### When to Clear

- **Before tests**: Ensure no stale bulletins from previous runs
- **After tests**: Clean up before next test
- **NOT for hiding problems**: Clear only when you've addressed the underlying issue

---

## 4. Interpreting Bulletins

### Common Bulletin Sources

| Source Type | Common Causes |
|-------------|---------------|
| PROCESSOR | Connection failures, invalid data, resource exhaustion |
| CONTROLLER_SERVICE | Missing configuration, auth failures, certificate issues |
| INPUT_PORT / OUTPUT_PORT | Connection or routing issues |
| REMOTE_PROCESS_GROUP | Site-to-site connection failures |

### Timestamp Awareness

Bulletins remain visible for 5 minutes by default, even after the issue is resolved. When troubleshooting:
- Check the `timestamp` field to ensure you're looking at current issues
- Stale bulletins (> 5 min old) have already expired from the system
- After fixing an issue, wait or clear bulletins to confirm resolution

---

## 5. Common Patterns

### Check for Errors After Deploy

```bash
# Deploy and start flow
nipyapi --profile <profile> ci deploy_flow --bucket <bucket> --flow <flow>
nipyapi --profile <profile> ci start_flow --process_group_id "<pg-id>"

# Wait briefly for any startup errors
sleep 5

# Check status
STATUS=$(nipyapi --profile <profile> ci get_status --process_group_id "<pg-id>")
ERRORS=$(echo "$STATUS" | jq -r '.bulletin_errors')

if [ "$ERRORS" != "0" ]; then
    echo "Flow has errors - investigating bulletins..."
    nipyapi --profile <profile> bulletins get_bulletin_board --pg_id "<pg-id>"
fi
```

### Clean State Between Tests

```bash
# Before test
nipyapi --profile <profile> bulletins clear_all_bulletins --pg_id "<pg-id>"

# Run test operations...

# After test - check for errors
nipyapi --profile <profile> ci get_status --process_group_id "<pg-id>"
```

### Investigate Controller Service Failure

When a controller service fails to enable:

```python
import nipyapi
nipyapi.profiles.switch('<profile>')

pg_id = "<pg-id>"

# Get bulletins filtered to controller services
bulletins = nipyapi.bulletins.get_bulletin_board(pg_id=pg_id)
cs_bulletins = [b for b in bulletins if b.source_type == 'CONTROLLER_SERVICE']

for b in cs_bulletins:
    print(f"Controller: {b.source_name}")
    print(f"Error: {b.message}")
    if b.stack_trace:
        # Stack trace often contains the root cause
        lines = b.stack_trace.split('Caused by:')
        if len(lines) > 1:
            print(f"Root cause: {lines[-1][:200]}")
```

---

## Curl Alternatives

For environments using curl. Ensure `$BASE_URL` and `$AUTH_HEADER` are set from your nipyapi profile (see `references/core-guidelines.md` section 4).

### Get Bulletin Board (curl)

```bash
PG_ID="<pg-id>"
curl -sk -H "$AUTH_HEADER" "$BASE_URL/flow/bulletin-board?groupId=$PG_ID" | \
  jq '.bulletinBoard.bulletins[] | {level: .bulletin.level, source: .bulletin.sourceName, message: .bulletin.message}'
```

### Clear Bulletins (curl, NiFi 2.7.0+ / Openflow 2025.12+)

```bash
PG_ID="<pg-id>"
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")

curl -sk -X POST -H "$AUTH_HEADER" -H "Content-Type: application/json" \
  -d "{\"fromTimestamp\": \"$TIMESTAMP\", \"id\": \"$PG_ID\"}" \
  "$BASE_URL/flow/process-groups/$PG_ID/bulletins/clear-requests"
```

---

## Next Step

After investigating bulletins:
- If controller service issue, check configuration (see `references/ops-config-verification.md`)
- If network issue, see `references/platform-eai.md`
- If authentication issue, see `references/ops-snowflake-auth.md` or `references/setup-auth.md`
- Return to calling workflow to continue

## Related References

- `references/ops-flow-lifecycle.md` - Start, stop, status operations
- `references/platform-diagnostics.md` - Runtime-level issues
- `references/ops-config-verification.md` - Validate configuration
