Armory spoofs itself as a node to your Core instance in order to get new mempool entries, new block notifications and push transactions. There is no ACK from a Core node when you send it a transactions through the p2p protocol. You can only query the node's mempool for your transaction's hash to figure whether it made it in.
This is the timeout mechanic; Armory isn't gonna hang forever for the transactions to make it in. It doesn't mean Core didn't accept the tx. Core tends to batch transactions together before processing them and pushing them to other nodes. This can delay the entry of your specific tx in the mempool to the point that Armory just gives up and assumes the tx didnt make it in.
Eventually, I added a fallback to use the RPC, which gives you an actual ACK. You have to consider that at the time this stuff was designed, the RPC was much harder to setup, so RPC broadcast never was considered a default. You still get the error message because ArmoryQt brokers the RPC connection so it hsa to be made aware of p2p broadcast fails in other to attempt a RPC push.
1. Why did the transaction not go through the first time, but did the second time?
Possibly an actual timeout where Armory didn't deliver the tx to Core before the query window expired. To push a tx, Armory has to announce it has one, by hash, and Core has to ask for its body. This part of the exchange can timeout as well (Armory just waits 10 seconds before calling a timeout, it doesn't care which part of the process it failed at). Usually timeouts occur at the second half: Core took the tx body and Armory is polling Core's mempool to see if the tx made it in.
What is the meaning of the error and how can I avoid it?
You can't avoid this error in the current Armory. Even if you have RPC up, you will be notified of a p2p broadcast timeout if that actually happens. If your RPC is set up, the fallback should see you through regardless.
The new broadcast code in the upcoming release deals with this stuff directly on the DB side (ArmoryQt doesn't talk to Core anymore, it's all handled by ArmoryDB). It also has a better way of handling Core mempool polling so the timeouts are less likely to occur.
Is there anything else to keep in mind in this context? For example, are there any risks in accidentally broadcasting a "_SENT" multiple times?
You can't rebroadcast a tx that is already in your node's mempool or the blockchain itself. Current version has poor verbose around this. Next version gives you a fuller error report in this kind of cases.
There are no short term security concerns here. You can't modify a signed tx, just broadcast it. If your intent was to get this tx into the blockchain, you're fine. In the long term, you shouldn't leave a transaction you signed but didn't broadcast hang around on an online machine
*if your intent is to not broadcast it in the future*. A valid, signed tx is as good as coins spent, you should either broadcast it or double spend one of the underlying utxos to invalidate it.