diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc
index 24f1a481..df2a1ef7 100644
--- a/src/xml/xml_native_writer.cc
+++ b/src/xml/xml_native_writer.cc
@@ -1321,7 +1321,11 @@ void mjXWriter::Body(XMLElement* elem, mjCBody* body) {
if (body!=model->GetWorld()) {
WriteAttrTxt(elem, "name", body->name);
WriteAttrTxt(elem, "childclass", body->classname);
- WriteAttr(elem, "pos", 3, body->locpos);
+
+ // write pos if it's not {0, 0, 0}
+ if (body->locpos[0] || body->locpos[1] || body->locpos[2]) {
+ WriteAttr(elem, "pos", 3, body->locpos);
+ }
WriteAttr(elem, "quat", 4, body->locquat, unitq);
if (body->mocap) {
WriteAttrKey(elem, "mocap", bool_map, 2, 1);
diff --git a/test/xml/xml_native_writer_test.cc b/test/xml/xml_native_writer_test.cc
index b125c9b5..7de399f0 100644
--- a/test/xml/xml_native_writer_test.cc
+++ b/test/xml/xml_native_writer_test.cc
@@ -601,6 +601,23 @@ TEST_F(XMLWriterTest, WritesGravComp) {
mj_deleteModel(model);
}
+TEST_F(XMLWriterTest, WritesBodyPos) {
+ static constexpr char xml[] = R"(
+
+
+
+
+
+
+ )";
+ mjModel* model = LoadModelFromString(xml);
+ ASSERT_THAT(model, NotNull());
+ std::string saved_xml = SaveAndReadXml(model);
+ EXPECT_THAT(saved_xml, HasSubstr("pos=\"1 2 3\""));
+ EXPECT_THAT(saved_xml, Not(HasSubstr("pos=\"0 0 0\"")));
+ mj_deleteModel(model);
+}
+
TEST_F(XMLWriterTest, UndefinedMassDensity) {
static constexpr char xml[] = R"(