A mutate filter does things in a fixed order, and copy comes after split, so when split executes the [tmp_message] field does not exist.
Break your mutate into two filters, with copy in the first and split and add_field (which is done last) in the second. I would do it as
mutate {
copy => { "cefmessage" => "[@metadata][cefmessage]" }
}
mutate {
split => { "[@metadata][cefmessage]" => "|" }
add_field => {
"cef_device_vendor" => "%{[@metadata][cefmessage][1]}"
"cef_device_product" => "%{[@metadata][cefmessage][3]}"
"cef_device_version" => "%{[@metadata][cefmessage][4]}"
}
}
Fields under [@metadata] are not indexed.
If you want to parse all of the CEF data then you may be able to do it using the cef codec.